From: Larry Sachs Date: Mon, 9 Jan 2017 01:00:38 +0000 (-0800) Subject: Add SimpleClientServer App. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3d99aa73931ef50110a73585d3e498c969b83c92;p=contrib%2Fiotivity.git Add SimpleClientServer App. Combines SimpleServer and SimpleClient into a single app. If there are errors, return code is non-zero. To build: $ scons TARGET_TRANSPORT=IP SECURED=0 RELEASE=1 BUILD_JAVA=ON To run: $ export LD_LIBRARY_PATH="/out/linux/x86_64/release/" $ java -cp java/examples-java/simpleclientserver/build/libs/simpleclientserver.jar:\ java/iotivity-linux/build/libs/iotivity-linux.jar org.iotivity.base.examples.SimpleClientServer ;\ echo result code = $? Change-Id: I8f4bcd04ecd41518694b1e9901b7dcc84da4c6fd Signed-off-by: Larry Sachs Reviewed-on: https://gerrit.iotivity.org/gerrit/16239 Tested-by: jenkins-iotivity Reviewed-by: George Nash Reviewed-by: Rick Bell --- diff --git a/java/examples-java/settings.gradle b/java/examples-java/settings.gradle index 126def3..2c00535 100755 --- a/java/examples-java/settings.gradle +++ b/java/examples-java/settings.gradle @@ -1 +1 @@ -include ':simpleserver', ':simpleclient'//, ':fridgeserver', ':fridgeclient', ':guiclient', ':provisioningclient', ':presenceserver', ':presenceclient', ':devicediscoveryclient', ':devicediscoveryserver', ':groupclient', ':groupserver', ':fridgegroupclient', ':fridgegroupserver' +include ':simpleserver', ':simpleclient', ':simpleclientserver'//, ':fridgeserver', ':fridgeclient', ':guiclient', ':provisioningclient', ':presenceserver', ':presenceclient', ':devicediscoveryclient', ':devicediscoveryserver', ':groupclient', ':groupserver', ':fridgegroupclient', ':fridgegroupserver' diff --git a/java/examples-java/simpleclientserver/.gitignore b/java/examples-java/simpleclientserver/.gitignore new file mode 100644 index 0000000..3543521 --- /dev/null +++ b/java/examples-java/simpleclientserver/.gitignore @@ -0,0 +1 @@ +/build diff --git a/java/examples-java/simpleclientserver/build.gradle b/java/examples-java/simpleclientserver/build.gradle new file mode 100644 index 0000000..e69de29 diff --git a/java/examples-java/simpleclientserver/src/main/assets/oic_svr_db_client.json b/java/examples-java/simpleclientserver/src/main/assets/oic_svr_db_client.json new file mode 100644 index 0000000..c16acb8 --- /dev/null +++ b/java/examples-java/simpleclientserver/src/main/assets/oic_svr_db_client.json @@ -0,0 +1,50 @@ +{ + "acl": [ + { + "sub": "Kg==", + "rsrc": [ + "/oic/res", + "/oic/d", + "/oic/p", + "/oic/res/types/d", + "/oic/ad", + "/oic/sec/acl" + ], + "perms": 2, + "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="] + }, + { + "sub": "Kg==", + "rsrc": [ + "/oic/sec/doxm", + "/oic/sec/pstat" + ], + "perms": 2, + "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="] + } + ], + "pstat": { + "isop": true, + "deviceid": "ZGV2aWNlaWQAAAAAABhanw==", + "ch": 0, + "cm": 0, + "tm": 0, + "om": 3, + "sm": [3] + }, + "doxm": { + "oxm": [0], + "oxmsel": 0, + "sct": 1, + "owned": true, + "deviceid": "MjIyMjIyMjIyMjIyMjIyMg==", + "ownr": "MjIyMjIyMjIyMjIyMjIyMg==" + }, + "cred": [{ + "credid": 1, + "sub": "MTExMTExMTExMTExMTExMQ==", + "credtyp": 1, + "pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==", + "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="] + }] +} diff --git a/java/examples-java/simpleclientserver/src/main/java/org/iotivity/base/examples/ServerLight.java b/java/examples-java/simpleclientserver/src/main/java/org/iotivity/base/examples/ServerLight.java new file mode 100644 index 0000000..baef3f6 --- /dev/null +++ b/java/examples-java/simpleclientserver/src/main/java/org/iotivity/base/examples/ServerLight.java @@ -0,0 +1,317 @@ +/* + ******************************************************************* + * + * Copyright 2017 Intel Corporation. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base.examples; + +import org.iotivity.base.EntityHandlerResult; +import org.iotivity.base.ErrorCode; +import org.iotivity.base.ObservationInfo; +import org.iotivity.base.OcException; +import org.iotivity.base.OcPlatform; +import org.iotivity.base.OcRepresentation; +import org.iotivity.base.OcResource; +import org.iotivity.base.OcResourceHandle; +import org.iotivity.base.OcResourceRequest; +import org.iotivity.base.OcResourceResponse; +import org.iotivity.base.RequestHandlerFlag; +import org.iotivity.base.RequestType; +import org.iotivity.base.ResourceProperty; + +import java.util.EnumSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * ServerLight + *

+ * This class represents a server light resource. + */ +public class ServerLight extends SimpleLight implements OcPlatform.EntityHandler { + + private static final String TAG = ServerLight.class.getSimpleName(); + + public static final String DEFAULT_RESOURCE_URI = "/a/light"; + public static final String DEFAULT_RESOURCE_NAME = "John's light"; + + private SimpleServer mServer; // server + private String mResourceUri; // resource URI + private String mResourceTypeName; // resource type name + private String mResourceInterface; // resource interface + private OcResourceHandle mResourceHandle; // resource handle + + private Thread mObserverNotifier; + + public ServerLight(SimpleServer server, String resourceUri, String name, boolean state, int power) { + mServer = server; + mResourceUri = resourceUri; + mResourceTypeName = SimpleLight.RESOURCE_TYPE; + mResourceInterface = OcPlatform.DEFAULT_INTERFACE; + mResourceHandle = null; // this is set when resource is registered + + setName(name); + setState(state); + setPower(power); + } + + public synchronized void registerResource() throws OcException { + if (null == mResourceHandle) { + mResourceHandle = OcPlatform.registerResource(mResourceUri, mResourceTypeName, mResourceInterface, this, + EnumSet.of(ResourceProperty.DISCOVERABLE, ResourceProperty.OBSERVABLE)); + } + } + + /** + * NOTE: This is just a sample implementation of entity handler. Entity + * handler can be implemented in several ways by the manufacturer. + */ + @Override + public synchronized EntityHandlerResult handleEntity(final OcResourceRequest request) { + EntityHandlerResult ehResult = EntityHandlerResult.ERROR; + if (null == request) { + msg("Server request is invalid"); + return ehResult; + } + // Get the request flags + EnumSet requestFlags = request.getRequestHandlerFlagSet(); + if (requestFlags.contains(RequestHandlerFlag.INIT)) { + msg("\t\tRequest Flag: Init"); + ehResult = EntityHandlerResult.OK; + } + if (requestFlags.contains(RequestHandlerFlag.REQUEST)) { + msg("\t\tRequest Flag: Request"); + ehResult = handleRequest(request); + } + if (requestFlags.contains(RequestHandlerFlag.OBSERVER)) { + msg("\t\tRequest Flag: Observer"); + ehResult = handleObserver(request); + } + return ehResult; + } + + private EntityHandlerResult handleRequest(OcResourceRequest request) { + EntityHandlerResult ehResult = EntityHandlerResult.ERROR; + // Check for query params (if any) + Map queries = request.getQueryParameters(); + if (!queries.isEmpty()) { + msg("Query processing is up to entityHandler"); + } else { + msg("No query parameters in this request"); + } + + for (Map.Entry entry : queries.entrySet()) { + msg("Query key: " + entry.getKey() + " value: " + entry.getValue()); + } + + // Get the request type + RequestType requestType = request.getRequestType(); + switch (requestType) { + case GET: + msg("\t\t\tRequest Type is GET"); + ehResult = handleGetRequest(request); + break; + case PUT: + msg("\t\t\tRequest Type is PUT"); + ehResult = handlePutRequest(request); + break; + case POST: + msg("\t\t\tRequest Type is POST"); + ehResult = handlePostRequest(request); + break; + case DELETE: + msg("\t\t\tRequest Type is DELETE"); + ehResult = handleDeleteRequest(); + break; + } + return ehResult; + } + + private EntityHandlerResult handleGetRequest(final OcResourceRequest request) { + EntityHandlerResult ehResult; + OcResourceResponse response = new OcResourceResponse(); + response.setRequestHandle(request.getRequestHandle()); + response.setResourceHandle(request.getResourceHandle()); + + response.setResponseResult(EntityHandlerResult.OK); + response.setResourceRepresentation(getOcRepresentation()); + ehResult = sendResponse(response); + return ehResult; + } + + private EntityHandlerResult handlePutRequest(OcResourceRequest request) { + OcResourceResponse response = new OcResourceResponse(); + response.setRequestHandle(request.getRequestHandle()); + response.setResourceHandle(request.getResourceHandle()); + + setOcRepresentation(request.getResourceRepresentation()); + response.setResourceRepresentation(getOcRepresentation()); + response.setResponseResult(EntityHandlerResult.OK); + return sendResponse(response); + } + + private int sUriCounter = 1; + + private EntityHandlerResult handlePostRequest(OcResourceRequest request) { + OcResourceResponse response = new OcResourceResponse(); + response.setRequestHandle(request.getRequestHandle()); + response.setResourceHandle(request.getResourceHandle()); + String newUri = DEFAULT_RESOURCE_URI + "/" + (++sUriCounter); + mServer.createNewLightResource(newUri, DEFAULT_RESOURCE_NAME + " " + sUriCounter); + OcRepresentation rep_post = getOcRepresentation(); + try { + rep_post.setValue(OcResource.CREATED_URI_KEY, newUri); + } catch (OcException e) { + msgError(TAG, e.toString()); + } + response.setResourceRepresentation(rep_post); + response.setNewResourceUri(newUri); + response.setResponseResult(EntityHandlerResult.RESOURCE_CREATED); + return sendResponse(response); + } + + private EntityHandlerResult handleDeleteRequest() { + try { + unregisterResource(); + return EntityHandlerResult.RESOURCE_DELETED; + } catch (OcException e) { + msgError(TAG, e.toString()); + msg("Failed to unregister a light resource"); + return EntityHandlerResult.ERROR; + } + } + + private List mObservationIds = new LinkedList<>(); + + private EntityHandlerResult handleObserver(final OcResourceRequest request) { + ObservationInfo observationInfo = request.getObservationInfo(); + switch (observationInfo.getObserveAction()) { + case REGISTER: + mObservationIds.add(observationInfo.getOcObservationId()); + break; + case UNREGISTER: + mObservationIds.remove((Byte) observationInfo.getOcObservationId()); + break; + } + // Observation happens on a different thread in notifyObservers method. + // If we have not created the thread already, we will create one here. + if (null == mObserverNotifier) { + mObserverNotifier = new Thread(new Runnable() { + public void run() { + notifyObservers(request); + } + }); + mObserverNotifier.start(); + } + return EntityHandlerResult.OK; + } + + private void notifyObservers(OcResourceRequest request) { + while (true) { + // increment current power value by 10 every 2 seconds + setPower(getPower() + 10); + sleep(2); + + msg("Notifying observers..."); + msg(toString()); + try { + OcPlatform.notifyAllObservers(mResourceHandle); + } catch (OcException e) { + ErrorCode errorCode = e.getErrorCode(); + if (ErrorCode.NO_OBSERVERS == errorCode) { + msg("No more observers, stopping notifications"); + } + return; + } + } + } + + private EntityHandlerResult sendResponse(OcResourceResponse response) { + try { + OcPlatform.sendResponse(response); + return EntityHandlerResult.OK; + } catch (OcException e) { + msgError(TAG, e.toString()); + msg("Failed to send response"); + return EntityHandlerResult.ERROR; + } + } + + public synchronized void unregisterResource() throws OcException { + if (null != mResourceHandle) { + OcPlatform.unregisterResource(mResourceHandle); + } + } + + public void setOcRepresentation(OcRepresentation rep) { + try { + if (rep.hasAttribute(NAME_KEY)) + setName((String) rep.getValue(NAME_KEY)); + if (rep.hasAttribute(STATE_KEY)) + setState((boolean) rep.getValue(STATE_KEY)); + if (rep.hasAttribute(POWER_KEY)) + setPower((int) rep.getValue(POWER_KEY)); + } catch (OcException e) { + msgError(TAG, e.toString()); + msg("Failed to get representation values"); + } + } + + public OcRepresentation getOcRepresentation() { + OcRepresentation rep = new OcRepresentation(); + try { + rep.setValue(NAME_KEY, getName()); + rep.setValue(STATE_KEY, getState()); + rep.setValue(POWER_KEY, getPower()); + } catch (OcException e) { + msgError(TAG, e.toString()); + msg("Failed to set representation values"); + } + return rep; + } + + // ****************************************************************************** + // End of the OIC specific code + // ****************************************************************************** + + @Override + public String toString() { + return "\t" + "URI" + ": " + mResourceUri + "\n\t" + NAME_KEY + ": " + getName() + "\n\t" + STATE_KEY + ": " + + getState() + "\n\t" + POWER_KEY + ": " + getPower(); + } + + private void sleep(int seconds) { + try { + Thread.sleep(seconds * 1000); + } catch (InterruptedException e) { + e.printStackTrace(); + msgError(TAG, e.toString()); + } + } + + private void msg(String text) { + mServer.msg(text); + } + + private void msgError(String tag, String text) { + mServer.msgError(tag, text); + } +} diff --git a/java/examples-java/simpleclientserver/src/main/java/org/iotivity/base/examples/SimpleClient.java b/java/examples-java/simpleclientserver/src/main/java/org/iotivity/base/examples/SimpleClient.java new file mode 100644 index 0000000..6ab4517 --- /dev/null +++ b/java/examples-java/simpleclientserver/src/main/java/org/iotivity/base/examples/SimpleClient.java @@ -0,0 +1,536 @@ +/* + ******************************************************************* + * + * Copyright 2017 Intel Corporation. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base.examples; + +import org.iotivity.base.ErrorCode; +import org.iotivity.base.ObserveType; +import org.iotivity.base.OcConnectivityType; +import org.iotivity.base.OcException; +import org.iotivity.base.OcHeaderOption; +import org.iotivity.base.OcPlatform; +import org.iotivity.base.OcRepresentation; +import org.iotivity.base.OcResource; +import org.iotivity.base.OcResourceIdentifier; + +import java.util.EnumSet; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * SimpleClient + *

+ * SimpleClient is a sample client app which should be started after the + * SimpleServer is started. It finds resources advertised by the server and + * calls different operations on it (GET, PUT, POST, DELETE and OBSERVE). + */ +public class SimpleClient implements OcPlatform.OnResourceFoundListener, OcResource.OnGetListener, + OcResource.OnPutListener, OcResource.OnPostListener, OcResource.OnObserveListener { + + private Map mFoundResources = new HashMap<>(); + private OcResource mFoundLightResource; + private boolean isDone; + private Object mWaitLock; + // local representation of a client's light resource + private SimpleLight mLight = new SimpleLight(); + + public SimpleClient(Object waitLock) { + mWaitLock = waitLock; + + try { + msg("Finding all resources of type \""+SimpleLight.RESOURCE_TYPE+"\"."); + String requestUri = OcPlatform.WELL_KNOWN_QUERY + "?rt="+SimpleLight.RESOURCE_TYPE; + OcPlatform.findResource("", requestUri, EnumSet.of(OcConnectivityType.CT_DEFAULT), this); + + /* + * Find resource is done twice so that we discover the original + * resources a second time. These resources will have the same + * unique identifier (yet be different objects), so that we can + * verify/show the duplicate-checking code in foundResource(above); + */ + msg("Finding all resources of type \""+SimpleLight.RESOURCE_TYPE+"\" for the second time"); + OcPlatform.findResource("", requestUri, EnumSet.of(OcConnectivityType.CT_DEFAULT), this); + + } catch (OcException e) { + msgError(e.toString()); + msg("Failed to invoke find resource API"); + } + + printLine(); + } + + public boolean isRunning() { + return !isDone; + } + + /** + * An event handler to be executed whenever a "findResource" request + * completes successfully + * + * @param ocResource + * found resource + */ + @Override + public synchronized void onResourceFound(OcResource ocResource) { + if (null == ocResource) { + msg("Found resource is invalid"); + return; + } + + if (mFoundResources.containsKey(ocResource.getUniqueIdentifier())) { + msg("Found a previously seen resource again!"); + } else { + msg("Found resource for the first time on server with ID: " + ocResource.getServerId()); + mFoundResources.put(ocResource.getUniqueIdentifier(), ocResource); + } + + if (null != mFoundLightResource) { + msg("Found another resource, ignoring"); + return; + } + + // Get the resource URI + String resourceUri = ocResource.getUri(); + // Get the resource host address + String hostAddress = ocResource.getHost(); + msg("\tURI of the resource: " + resourceUri); + msg("\tHost address of the resource: " + hostAddress); + // Get the resource types + msg("\tList of resource types: "); + for (String resourceType : ocResource.getResourceTypes()) { + msg("\t\t" + resourceType); + } + msg("\tList of resource interfaces:"); + for (String resourceInterface : ocResource.getResourceInterfaces()) { + msg("\t\t" + resourceInterface); + } + msg("\tList of resource connectivity types:"); + for (OcConnectivityType connectivityType : ocResource.getConnectivityTypeSet()) { + msg("\t\t" + connectivityType); + } + printLine(); + + // In this example we are only interested in the light resources + if (resourceUri.equals(ServerLight.DEFAULT_RESOURCE_URI)) { + mFoundLightResource = ocResource; + + // Call a local method which will internally invoke "get" API on the + // foundLightResource + getLightResourceRepresentation(); + } + } + + @Override + public synchronized void onFindResourceFailed(Throwable throwable, String uri) { + msg("findResource request has failed"); + msgError(throwable.toString()); + } + + /** + * Local method to get representation of a found light resource + */ + private void getLightResourceRepresentation() { + msg("Getting Light Representation..."); + + Map queryParams = new HashMap<>(); + try { + // Invoke resource's "get" API with a OcResource.OnGetListener event + // listener implementation + mFoundLightResource.get(queryParams, this); + } catch (OcException e) { + msgError(e.toString()); + msg("Error occurred while invoking \"get\" API"); + } + } + + /** + * An event handler to be executed whenever a "get" request completes + * successfully + * + * @param list + * list of the header options + * @param ocRepresentation + * representation of a resource + */ + @Override + public synchronized void onGetCompleted(List list, OcRepresentation ocRepresentation) { + msg("GET request was successful"); + msg("Resource URI: " + ocRepresentation.getUri()); + + try { + // Read attribute values into local representation of a light + mLight.setOcRepresentation(ocRepresentation); + } catch (OcException e) { + msgError(e.toString()); + msg("Failed to read the attributes of a light resource"); + } + msg("Light attributes: "); + msg(mLight.toString()); + printLine(); + + // Call a local method which will internally invoke put API on the + // foundLightResource + putLightRepresentation(); + } + + /** + * An event handler to be executed whenever a "get" request fails + * + * @param throwable + * exception + */ + @Override + public synchronized void onGetFailed(Throwable throwable) { + if (throwable instanceof OcException) { + OcException ocEx = (OcException) throwable; + msgError(ocEx.toString()); + ErrorCode errCode = ocEx.getErrorCode(); + // do something based on errorCode + msg("Error code: " + errCode); + } + msg("Failed to get representation of a found light resource"); + } + + /** + * Local method to put a different state for this light resource + */ + private void putLightRepresentation() { + // set new values + mLight.setState(true); + mLight.setPower(15); + + msg("Putting light representation..."); + OcRepresentation representation = null; + try { + representation = mLight.getOcRepresentation(); + } catch (OcException e) { + msgError(e.toString()); + msg("Failed to get OcRepresentation from a light"); + } + + Map queryParams = new HashMap<>(); + + try { + // Invoke resource's "put" API with a new representation, query + // parameters and OcResource.OnPutListener event listener + // implementation + mFoundLightResource.put(representation, queryParams, this); + } catch (OcException e) { + msgError(e.toString()); + msg("Error occurred while invoking \"put\" API"); + } + } + + /** + * An event handler to be executed whenever a "put" request completes + * successfully + * + * @param list + * list of the header options + * @param ocRepresentation + * representation of a resource + */ + @Override + public synchronized void onPutCompleted(List list, OcRepresentation ocRepresentation) { + msg("PUT request was successful"); + try { + mLight.setOcRepresentation(ocRepresentation); + } catch (OcException e) { + msgError(e.toString()); + msg("Failed to create Light representation"); + } + msg("Light attributes: "); + msg(mLight.toString()); + printLine(); + + // Call a local method which will internally invoke post API on the + // foundLightResource + postLightRepresentation(); + } + + /** + * An event handler to be executed whenever a "put" request fails + * + * @param throwable + * exception + */ + @Override + public synchronized void onPutFailed(Throwable throwable) { + if (throwable instanceof OcException) { + OcException ocEx = (OcException) throwable; + msgError(ocEx.toString()); + ErrorCode errCode = ocEx.getErrorCode(); + // do something based on errorCode + msg("Error code: " + errCode); + } + msg("Failed to \"put\" a new representation"); + } + + /** + * Local method to post a different state for this light resource + */ + private void postLightRepresentation() { + // set new values + mLight.setState(false); + mLight.setPower(105); + + msg("Posting light representation..."); + OcRepresentation representation = null; + try { + representation = mLight.getOcRepresentation(); + } catch (OcException e) { + msgError(e.toString()); + msg("Failed to get OcRepresentation from a light"); + } + + Map queryParams = new HashMap<>(); + try { + // Invoke resource's "post" API with a new representation, query + // parameters and OcResource.OnPostListener event listener + // implementation + mFoundLightResource.post(representation, queryParams, this); + } catch (OcException e) { + msgError(e.toString()); + msg("Error occurred while invoking \"post\" API"); + } + } + + /** + * An event handler to be executed whenever a "post" request completes + * successfully + * + * @param list + * list of the header options + * @param ocRepresentation + * representation of a resource + */ + @Override + public synchronized void onPostCompleted(List list, OcRepresentation ocRepresentation) { + msg("POST request was successful"); + try { + if (ocRepresentation.hasAttribute(OcResource.CREATED_URI_KEY)) { + msg("\tUri of the created resource: " + ocRepresentation.getValue(OcResource.CREATED_URI_KEY)); + } else { + mLight.setOcRepresentation(ocRepresentation); + msg(mLight.toString()); + } + } catch (OcException e) { + msgError(e.toString()); + } + + // setting new values + mLight.setState(true); + mLight.setPower(55); + msg("Posting again light representation..."); + OcRepresentation representation2 = null; + try { + representation2 = mLight.getOcRepresentation(); + } catch (OcException e) { + msgError(e.toString()); + msg("Failed to get OcRepresentation from a light"); + } + + Map queryParams = new HashMap<>(); + try { + // Invoke resource's "post" API with a new representation, query + // parameters and OcResource.OnPostListener event listener + // implementation + mFoundLightResource.post(representation2, queryParams, onPostListener2); + } catch (OcException e) { + msgError(e.toString()); + msg("Error occurred while invoking \"post\" API"); + } + } + + /** + * An event handler to be executed whenever a "post" request fails + * + * @param throwable + * exception + */ + @Override + public synchronized void onPostFailed(Throwable throwable) { + if (throwable instanceof OcException) { + OcException ocEx = (OcException) throwable; + msgError(ocEx.toString()); + ErrorCode errCode = ocEx.getErrorCode(); + // do something based on errorCode + msg("Error code: " + errCode); + } + msg("Failed to \"post\" a new representation"); + } + + /** + * Declare and implement a second OcResource.OnPostListener + */ + OcResource.OnPostListener onPostListener2 = new OcResource.OnPostListener() { + /** + * An event handler to be executed whenever a "post" request completes + * successfully + * + * @param list + * list of the header options + * @param ocRepresentation + * representation of a resource + */ + @Override + public synchronized void onPostCompleted(List list, OcRepresentation ocRepresentation) { + msg("Second POST request was successful"); + try { + if (ocRepresentation.hasAttribute(OcResource.CREATED_URI_KEY)) { + msg("\tUri of the created resource: " + ocRepresentation.getValue(OcResource.CREATED_URI_KEY)); + } else { + mLight.setOcRepresentation(ocRepresentation); + msg(mLight.toString()); + } + } catch (OcException e) { + msgError(e.toString()); + } + + // Call a local method which will internally invoke observe API on + // the foundLightResource + observeFoundLightResource(); + } + + /** + * An event handler to be executed whenever a "post" request fails + * + * @param throwable + * exception + */ + @Override + public synchronized void onPostFailed(Throwable throwable) { + if (throwable instanceof OcException) { + OcException ocEx = (OcException) throwable; + msgError(ocEx.toString()); + ErrorCode errCode = ocEx.getErrorCode(); + // do something based on errorCode + msg("Error code: " + errCode); + } + msg("Failed to \"post\" a new representation"); + } + }; + + /** + * Local method to start observing this light resource + */ + private void observeFoundLightResource() { + try { + // Invoke resource's "observe" API with a observe type, query + // parameters and + // OcResource.OnObserveListener event listener implementation + mFoundLightResource.observe(ObserveType.OBSERVE, new HashMap(), this); + } catch (OcException e) { + msgError(e.toString()); + msg("Error occurred while invoking \"observe\" API"); + } + } + + // holds current number of observations + private int mObserveCount = 0; + + /** + * An event handler to be executed whenever a "post" request completes + * successfully + * + * @param list + * list of the header options + * @param ocRepresentation + * representation of a resource + * @param sequenceNumber + * sequence number + */ + @Override + public synchronized void onObserveCompleted(List list, OcRepresentation ocRepresentation, + int sequenceNumber) { + if (OcResource.OnObserveListener.REGISTER == sequenceNumber) { + msg("Observe registration action is successful:"); + } else if (OcResource.OnObserveListener.DEREGISTER == sequenceNumber) { + msg("Observe De-registration action is successful"); + } else if (OcResource.OnObserveListener.NO_OPTION == sequenceNumber) { + msg("Observe registration or de-registration action is failed"); + } + + msg("OBSERVE Result:"); + msg("\tSequenceNumber: " + sequenceNumber); + try { + mLight.setOcRepresentation(ocRepresentation); + } catch (OcException e) { + msgError(e.toString()); + msg("Failed to get the attribute values"); + } + msg(mLight.toString()); + + if ((++mObserveCount) > 11) { + msg("Cancelling Observe..."); + try { + mFoundLightResource.cancelObserve(); + } catch (OcException e) { + msgError(e.toString()); + msg("Error occurred while invoking \"cancelObserve\" API"); + } + msg("DONE"); + isDone = true; + + synchronized (mWaitLock) { + mWaitLock.notify(); + } + } + } + + /** + * An event handler to be executed whenever a "observe" request fails + * + * @param throwable + * exception + */ + @Override + public synchronized void onObserveFailed(Throwable throwable) { + if (throwable instanceof OcException) { + OcException ocEx = (OcException) throwable; + msgError(ocEx.toString()); + ErrorCode errCode = ocEx.getErrorCode(); + // do something based on errorCode + msg("Error code: " + errCode); + } + msg("Observation of the found light resource has failed"); + } + + // ****************************************************************************** + // End of the OIC specific code + // ****************************************************************************** + + private static final String TAG = SimpleClient.class.getSimpleName(); + + private void msg(final String text) { + SimpleClientServer.msg(TAG, text); + } + + private void msgError(final String text) { + SimpleClientServer.msgError(TAG, text); + } + + private void printLine() { + SimpleClientServer.printLine(TAG); + } +} diff --git a/java/examples-java/simpleclientserver/src/main/java/org/iotivity/base/examples/SimpleClientServer.java b/java/examples-java/simpleclientserver/src/main/java/org/iotivity/base/examples/SimpleClientServer.java new file mode 100644 index 0000000..e6152dd --- /dev/null +++ b/java/examples-java/simpleclientserver/src/main/java/org/iotivity/base/examples/SimpleClientServer.java @@ -0,0 +1,89 @@ +/* + ******************************************************************* + * + * Copyright 2017 Intel Corporation. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base.examples; + +import org.iotivity.base.ModeType; +import org.iotivity.base.OcException; +import org.iotivity.base.OcPlatform; +import org.iotivity.base.PlatformConfig; +import org.iotivity.base.QualityOfService; +import org.iotivity.base.ServiceType; + +import java.util.LinkedList; +import java.util.List; + +/** + * SimpleClientServer + *

+ * SimpleClientServer is a sample OIC client/server application. Return code is + * 0 if no errors detected. + */ +public class SimpleClientServer { + + private static final String TAG = SimpleClientServer.class.getSimpleName(); + + public static void main(String[] args) { + + PlatformConfig platformConfig = new PlatformConfig(ServiceType.IN_PROC, ModeType.CLIENT_SERVER, "0.0.0.0", 0, + QualityOfService.LOW); + msg(TAG, "Configuring platform."); + OcPlatform.Configure(platformConfig); + + SimpleServer server = new SimpleServer(); + Object waitLock = new Object(); + SimpleClient client = new SimpleClient(waitLock); + + int returnCode = -1; + synchronized (waitLock) { + try { + waitLock.wait(60 * 1000); + if (client.isRunning()) { + msgError(TAG, "Failed to complete on time!"); + } else { + returnCode = 0; + } + } catch (InterruptedException e) { + msgError(TAG, e.toString()); + } + } + + server.stopSimpleServer(); + System.exit(returnCode); + } + + private static String getMessage(String tag, String text, boolean isError) { + return "[" + (isError ? "E" : "O") + "]" + tag + " | " + text; + } + + protected static void msg(final String tag, final String text) { + System.out.println(getMessage(tag, text, false)); + } + + protected static void msgError(final String tag, final String text) { + System.out.println(getMessage(tag, text, true)); + } + + protected static void printLine(final String tag) { + msg(tag, "------------------------------------------------------------------------"); + } +} diff --git a/java/examples-java/simpleclientserver/src/main/java/org/iotivity/base/examples/SimpleLight.java b/java/examples-java/simpleclientserver/src/main/java/org/iotivity/base/examples/SimpleLight.java new file mode 100644 index 0000000..9d33f33 --- /dev/null +++ b/java/examples-java/simpleclientserver/src/main/java/org/iotivity/base/examples/SimpleLight.java @@ -0,0 +1,95 @@ +/* + ******************************************************************* + * + * Copyright 2017 Intel Corporation. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base.examples; + +import org.iotivity.base.OcException; +import org.iotivity.base.OcRepresentation; + +/** + * SimpleLight + *

+ * This class is used by SimpleClient to create an object representation of a + * remote light resource and update the values depending on the server response. + */ +public class SimpleLight { + + public static final String RESOURCE_TYPE = "core.light"; + + public static final String NAME_KEY = "name"; + public static final String STATE_KEY = "state"; + public static final String POWER_KEY = "power"; + + private String mName; + private boolean mState; + private int mPower; + + public SimpleLight() { + mName = ""; + mState = false; + mPower = 0; + } + + public void setOcRepresentation(OcRepresentation rep) throws OcException { + mName = rep.getValue(NAME_KEY); + mState = rep.getValue(STATE_KEY); + mPower = rep.getValue(POWER_KEY); + } + + public OcRepresentation getOcRepresentation() throws OcException { + OcRepresentation rep = new OcRepresentation(); + rep.setValue(NAME_KEY, mName); + rep.setValue(STATE_KEY, mState); + rep.setValue(POWER_KEY, mPower); + return rep; + } + + public String getName() { + return mName; + } + + public void setName(String name) { + mName = name; + } + + public boolean getState() { + return mState; + } + + public void setState(boolean state) { + mState = state; + } + + public int getPower() { + return mPower; + } + + public void setPower(int power) { + mPower = power; + } + + @Override + public String toString() { + return "\t" + NAME_KEY + ": " + getName() + "\n\t" + STATE_KEY + ": " + getState() + "\n\t" + POWER_KEY + ": " + + getPower(); + } +} diff --git a/java/examples-java/simpleclientserver/src/main/java/org/iotivity/base/examples/SimpleServer.java b/java/examples-java/simpleclientserver/src/main/java/org/iotivity/base/examples/SimpleServer.java new file mode 100644 index 0000000..75fab01 --- /dev/null +++ b/java/examples-java/simpleclientserver/src/main/java/org/iotivity/base/examples/SimpleServer.java @@ -0,0 +1,94 @@ +/* + ******************************************************************* + * + * Copyright 2017 Intel Corporation. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base.examples; + +import org.iotivity.base.OcException; + +import java.util.LinkedList; +import java.util.List; + +/** + * SimpleServer + *

+ * SimpleServer is a sample OIC server application. It creates a Light and waits + * for the incoming client calls to handle various request scenarios. + */ +public class SimpleServer { + + private List lights = new LinkedList<>(); + + public SimpleServer() { + createNewLightResource(ServerLight.DEFAULT_RESOURCE_URI, ServerLight.DEFAULT_RESOURCE_NAME); + + msg("Waiting for the requests..."); + printLine(); + } + + protected void createNewLightResource(String resourceUri, String resourceName) { + msg("Creating a light"); + ServerLight light = new ServerLight(this, resourceUri, resourceName, false, 0); + msg(light.toString()); + + msg("Registering light as a resource"); + try { + light.registerResource(); + } catch (OcException e) { + msgError(TAG, e.toString()); + msg("Failed to register a light resource"); + } + lights.add(light); + } + + public void stopSimpleServer() { + for (ServerLight light : lights) { + try { + light.unregisterResource(); + } catch (OcException e) { + msgError(TAG, e.toString()); + msg("Failed to unregister a light resource"); + } + } + lights.clear(); + + msg("All created resources have been unregistered"); + printLine(); + } + + // ****************************************************************************** + // End of the OIC specific code + // ****************************************************************************** + + private static final String TAG = SimpleServer.class.getSimpleName(); + + protected void msg(final String text) { + SimpleClientServer.msg(TAG, text); + } + + protected void msgError(final String tag, final String text) { + SimpleClientServer.msgError(tag, text); + } + + private void printLine() { + SimpleClientServer.printLine(TAG); + } +}