simulator C++ modules.
Change-Id: I572a52907f16e06b9f0877e7dc150056d0aa7532
Signed-off-by: Harish Kumara Marappa <h.marappa@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/1870
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Madan Lanka <lanka.madan@samsung.com>
#include "simulator_manager.h"
+class AppLogger : public ILogger
+{
+ public:
+ void write(std::string time, ILogger::Level level, std::string message)
+ {
+ std::cout << "[APPLogger] " << time << " " << ILogger::getString(level) << " " << message;
+ }
+};
+std::shared_ptr<AppLogger> gAppLogger(new AppLogger());
+
class SimLightResource
{
public:
int selectResource()
{
+ if (0 == m_resources.size())
+ {
+ std::cout << "No resouces!" << std::endl;
+ return -1;
+ }
+
int index = 1;
for (auto & resource : m_resources)
{
std::cout << "#### Modified attributes are ####" << std::endl;
for (auto & attribute : resModel.getAttributes())
{
- std::cout << attribute.second.getName() << " : " << attribute.second.valueToString().c_str() << std::endl;
+ std::cout << attribute.second.getName() << " : " << attribute.second.valueToString().c_str() <<
+ std::endl;
}
std::cout << "########################" << std::endl;
}
int choice = -1;
std::cout << "Select the attribute which you want to automate for updation: " << std::endl;
std::cin >> choice;
- if (choice == -1 || choice > size)
+ if (choice < 0 || choice > size)
{
std::cout << "Invalid selection!" << std::endl;
return;
{
std::cout << "############### MAIN MENU###############" << std::endl;
std::cout << "1. Test simulation of light resource" << std::endl;
- std::cout << "2. Help" << std::endl;
+ std::cout << "2. Set Logger" << std::endl;
+ std::cout << "3. Help" << std::endl;
std::cout << "0. Exit" << std::endl;
std::cout << "######################################" << std::endl;
}
+void setLogger()
+{
+ std::cout << "1. Default console logger" << std::endl;
+ std::cout << "2. Default file logger" << std::endl;
+ std::cout << "3. custom logger" << std::endl;
+
+ int choice = -1;
+ std::cin >> choice;
+ if (choice <= 0 || choice > 3)
+ {
+ std::cout << "Invalid selection !" << std::endl;
+ return;
+ }
+
+ switch (choice)
+ {
+ case 1:
+ {
+ if (false == SimulatorManager::getInstance()->setDefaultConsoleLogger())
+ std::cout << "Failed to set the default console logger" << std::endl;
+ } break;
+ case 2:
+ {
+ std::string filePath;
+ std::cout << "Enter the file path (without file name) : ";
+ std::cin >> filePath;
+ if (false == SimulatorManager::getInstance()->setDefaultFileLogger(filePath))
+ std::cout << "Failed to set default file logger" << std::endl;
+ } break;
+ case 3: SimulatorManager::getInstance()->setLogger(gAppLogger);
+ }
+}
+
int main(void)
{
SimLightResource lightResource;
int choice = -1;
std::cout << "Enter your choice: ";
std::cin >> choice;
- if (choice < 0 || choice > 2)
+ if (choice < 0 || choice > 3)
{
std::cout << "Invaild choice !" << std::endl; continue;
}
case 1: lightResource.startTest();
std::cout << "Welcome back to main menu !" << std::endl;
break;
- case 2: printMainMenu(); break;
+ case 2: setLogger(); break;
+ case 3: printMainMenu(); break;
case 0: cont = false;
}
}
#include <vector>
#include "simulator_error_codes.h"
#include "simulator_resource.h"
+#include "simulator_logger.h"
/**
* @class SimulatorManager
*/
SimulatorResult deleteResources(const std::string &resourceType = "");
+ /**
+ * API for setting logger target for receiving the log messages.
+ *
+ * @param logger - ILogger interface for handling the log messages.
+ *
+ */
+ void setLogger(std::shared_ptr<ILogger> logger);
+
+ /**
+ * API for setting console as logger target.
+ *
+ * @return true if console set as logger target,
+ * otherwise false.
+ *
+ */
+ bool setDefaultConsoleLogger();
+
+ /**
+ * API for setting file as logger target.
+ *
+ * @param path - File to which log messages to be saved.
+ *
+ * @return true if console set as logger target,
+ * otherwise false.
+ *
+ */
+ bool setDefaultFileLogger(std::string &path);
+
private:
SimulatorManager();
};
#include <jni.h>
-static jfieldID GetHandleField(JNIEnv *env, jobject jobj)
-{
- jclass cls = env->GetObjectClass(jobj);
- return env->GetFieldID(cls, "nativeHandle", "J");
-}
-
-template <typename T>
-static T *GetHandle(JNIEnv *env, jobject jobj)
-{
- jlong handle = env->GetLongField(jobj, GetHandleField(env, jobj));
- return reinterpret_cast<T *>(handle);
-}
-
-template <typename T>
-static void SetHandle(JNIEnv *env, jobject jobj, T *type)
-{
- jlong handle = reinterpret_cast<jlong>(type);
-
- env->SetLongField(jobj, GetHandleField(env, jobj), handle);
-}
-
typedef struct
{
jclass classInteger;
jclass classDouble;
jclass classString;
jclass classHashMap;
+ jclass classVector;
jclass classSimulatorResource;
jclass classSimulatorResourceModel;
jclass classSimulatorResourceAttribute;
+ jclass classSimulatorRemoteResource;
+ jclass classSimulatorCallback;
jmethodID classIntegerCtor;
jmethodID classDoubleCtor;
jmethodID classHashMapCtor;
jmethodID classHashMapPut;
+ jmethodID classVectorCtor;
+ jmethodID classVectorAddElement;
jmethodID classSimulatorResourceCtor;
jmethodID classSimulatorResourceSetURI;
jmethodID classSimulatorResourceSetResourceType;
jmethodID classSimulatorResourceAttributeCtor;
} SimulatorClassRefs;
+static jfieldID GetHandleField(JNIEnv *env, jobject jobj)
+{
+ jclass cls = env->GetObjectClass(jobj);
+ return env->GetFieldID(cls, "nativeHandle", "J");
+}
+
+template <typename T>
+static T *GetHandle(JNIEnv *env, jobject jobj)
+{
+ jlong handle = env->GetLongField(jobj, GetHandleField(env, jobj));
+ return reinterpret_cast<T *>(handle);
+}
+
+template <typename T>
+static void SetHandle(JNIEnv *env, jobject jobj, T *type)
+{
+ jlong handle = reinterpret_cast<jlong>(type);
+
+ env->SetLongField(jobj, GetHandleField(env, jobj), handle);
+}
+
+JNIEnv *getEnv();
+void releaseEnv();
+
#endif
#include "simulator_common_jni.h"
#include "simulator_manager.h"
-#define SIMULATOR_RESOURCE_PATH "org/iotivity/simulator/SimulatorResourceServer"
-#define SIMULATOR_RESOURCE_TYPE "Lorg/iotivity/simulator/SimulatorResourceServer;"
+SimulatorClassRefs gSimulatorClassRefs;
+std::mutex gEnvMutex;
+JavaVM *gvm;
-#define SIMULATOR_RESOURCE_MODEL_PATH "org/iotivity/simulator/SimulatorResourceModel"
-#define SIMULATOR_RESOURCE_MODEL_TYPE "Lorg/iotivity/simulator/SimulatorResourceModel;"
+JNIEnv *getEnv()
+{
+ std::unique_lock<std::mutex> lock(gEnvMutex);
+ if (nullptr == gvm)
+ return NULL;
-#define SIMULATOR_RESOURCE_ATTRIBUTE_PATH "org/iotivity/simulator/SimulatorResourceAttribute"
-#define SIMULATOR_RESOURCE_ATTRIBUTE_TYPE "Lorg/iotivity/simulator/SimulatorResourceAttribute;"
+ JNIEnv *env = NULL;
+ jint ret = gvm->GetEnv((void **)&env, JNI_VERSION_1_6);
+ switch (ret)
+ {
+ case JNI_OK:
+ return env;
+ case JNI_EDETACHED:
+ if (0 == gvm->AttachCurrentThread((void **)&env, NULL))
+ return env;
+ }
+
+ return NULL;
+}
+
+void releaseEnv()
+{
+ std::unique_lock<std::mutex> lock(gEnvMutex);
+ if (nullptr == gvm)
+ return;
+ gvm->DetachCurrentThread();
+}
+
+class JNILogger : public ILogger
+{
+ public:
+ void setJavaLogger(JNIEnv *env, jobject logger)
+ {
+ m_logger = env->NewWeakGlobalRef(logger);
+ }
+
+ void write(std::string time, ILogger::Level level, std::string message)
+ {
+ JNIEnv *env = getEnv();
+ if (nullptr == env)
+ return;
+
+ jobject logger = env->NewLocalRef(m_logger);
+ if (!logger)
+ {
+ releaseEnv();
+ return;
+ }
+
+ jclass loggerCls = env->GetObjectClass(logger);
+ if (!loggerCls)
+ {
+ releaseEnv();
+ return;
+ }
+
+ jmethodID writeMId = env->GetMethodID(loggerCls, "write",
+ "(Ljava/lang/String;ILjava/lang/String;)V");
+ if (!writeMId)
+ {
+ releaseEnv();
+ return;
+ }
+
+ jstring msg = env->NewStringUTF(message.c_str());
+ jstring timeStr = env->NewStringUTF(time.c_str());
+ env->CallVoidMethod(logger, writeMId, timeStr, static_cast<jint>(level), msg);
+ env->DeleteLocalRef(msg);
+ env->DeleteLocalRef(timeStr);
+ releaseEnv();
+ }
+
+ private:
+ jweak m_logger;
+};
-SimulatorClassRefs gSimulatorClassRefs;
JNIEXPORT jobject JNICALL
Java_org_iotivity_simulator_SimulatorManagerNativeInterface_createResource
}
+JNIEXPORT void JNICALL
+Java_org_iotivity_simulator_SimulatorManagerNativeInterface_setLogger
+(JNIEnv *env, jclass object, jobject logger)
+{
+ static std::shared_ptr<ILogger> target(new JNILogger());
+ dynamic_cast<JNILogger *>(target.get())->setJavaLogger(env, logger);
+ SimulatorManager::getInstance()->setLogger(target);
+}
+
static bool getClassRef(JNIEnv *env, const char *className, jclass &classRef)
{
jclass localClassRef = nullptr;
return JNI_ERR;
}
- // Get the class references and constructor methods
+ // Get the class references
if (false == getClassRef(env, "java/lang/Integer", gSimulatorClassRefs.classInteger))
{
return JNI_ERR;
return JNI_ERR;
}
- if (false == getClassRef(env, SIMULATOR_RESOURCE_PATH, gSimulatorClassRefs.classSimulatorResource))
+ if (false == getClassRef(env, "java/util/Vector", gSimulatorClassRefs.classVector))
+ {
+ return JNI_ERR;
+ }
+
+ if (false == getClassRef(env, "org/oic/simulator/serviceprovider/SimulatorResourceServer",
+ gSimulatorClassRefs.classSimulatorResource))
{
return JNI_ERR;
}
- if (false == getClassRef(env, SIMULATOR_RESOURCE_MODEL_PATH,
+ if (false == getClassRef(env, "org/oic/simulator/serviceprovider/SimulatorResourceModel",
gSimulatorClassRefs.classSimulatorResourceModel))
{
return JNI_ERR;
}
- if (false == getClassRef(env, SIMULATOR_RESOURCE_ATTRIBUTE_PATH,
+ if (false == getClassRef(env, "org/oic/simulator/SimulatorResourceAttribute",
gSimulatorClassRefs.classSimulatorResourceAttribute))
{
return JNI_ERR;
}
- // Get the constructor methods
+ if (false == getClassRef(env, "org/oic/simulator/clientcontroller/SimulatorRemoteResource",
+ gSimulatorClassRefs.classSimulatorRemoteResource))
+ {
+ return JNI_ERR;
+ }
+
+
+ // Get the reference to methods
gSimulatorClassRefs.classIntegerCtor = env->GetMethodID(gSimulatorClassRefs.classInteger, "<init>",
"(I)V");
if (!gSimulatorClassRefs.classIntegerCtor)
if (!gSimulatorClassRefs.classHashMapPut)
return JNI_ERR;
+ gSimulatorClassRefs.classVectorCtor = env->GetMethodID(gSimulatorClassRefs.classVector, "<init>",
+ "()V");
+ if (!gSimulatorClassRefs.classVectorCtor)
+ return JNI_ERR;
+
+ gSimulatorClassRefs.classVectorAddElement = env->GetMethodID(gSimulatorClassRefs.classVector,
+ "addElement",
+ "(Ljava/lang/Object;)V");
+ if (!gSimulatorClassRefs.classVectorAddElement)
+ return JNI_ERR;
+
gSimulatorClassRefs.classSimulatorResourceCtor = env->GetMethodID(
gSimulatorClassRefs.classSimulatorResource, "<init>", "(J)V");
if (!gSimulatorClassRefs.classSimulatorResourceCtor)
if (!gSimulatorClassRefs.classSimulatorResourceAttributeCtor)
return JNI_ERR;
+ gvm = vm;
return JNI_VERSION_1_6;
}
JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved)
{
- JNIEnv *env = NULL;
- if (JNI_OK != vm->GetEnv((void **)&env, JNI_VERSION_1_6))
- {
- return;
- }
}
#ifdef __cplusplus
Java_org_iotivity_simulator_SimulatorManagerNativeInterface_deleteResources
(JNIEnv *env, jclass object, jstring resourceType);
+JNIEXPORT void JNICALL
+Java_org_iotivity_simulator_SimulatorManagerNativeInterface_setLogger
+(JNIEnv *env, jclass object, jobject logger);
+
#ifdef __cplusplus
}
#endif
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * 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.
+ *
+ ******************************************************************/
+
+#include "simulator_logger.h"
+#include <sstream>
+#include <fstream>
+#include <time.h>
+
+class ConsoleLogger : public ILogger
+{
+ public:
+ void write(std::string time, ILogger::Level level, std::string message)
+ {
+ std::ostringstream out;
+ out << time << " " << ILogger::getString(level) << " " << message;
+ std::cout << out.str() << std::endl;
+ }
+};
+
+class FileLogger : public ILogger
+{
+ public:
+ FileLogger(std::string filePath) : m_filePath(filePath) {}
+
+ bool open()
+ {
+ m_out.open(m_filePath, std::ofstream::out);
+ return m_out.is_open();
+ }
+
+ void close()
+ {
+ if (m_out.is_open())
+ m_out.close();
+ }
+
+ void write(std::string time, ILogger::Level level, std::string message)
+ {
+ m_out << time << " " << ILogger::getString(level) << " " << message;
+ }
+
+ private:
+ std::ofstream m_out;
+ std::string m_filePath;
+};
+
+bool Logger::setDefaultConsoleTarget()
+{
+ if (nullptr != m_target)
+ return false;
+
+ m_target = std::make_shared<ConsoleLogger>();
+ return true;
+}
+
+bool Logger::setDefaultFileTarget(std::string &path)
+{
+ if (nullptr != m_target || path.empty())
+ return false;
+
+ time_t timeInfo = time(NULL);
+ struct tm *localTime = localtime(&timeInfo);
+ std::ostringstream newFileName;
+ newFileName << path << "/Simulator_";
+ newFileName << localTime->tm_year << localTime->tm_mon << localTime->tm_mday << localTime->tm_hour
+ << localTime->tm_min << localTime->tm_sec;
+ newFileName << ".log";
+
+ std::shared_ptr<FileLogger> fileLogger(new FileLogger(newFileName.str()));
+ if (fileLogger->open())
+ {
+ m_target = fileLogger;
+ return true;
+ }
+
+ return false;
+}
+
+void Logger::setCustomTarget(std::shared_ptr<ILogger> target)
+{
+ m_target = target;
+}
+
+void Logger::write(ILogger::Level level, std::ostringstream &str)
+{
+ if (nullptr != m_target)
+ {
+ time_t timeInfo = time(NULL);
+ struct tm *localTime = localtime(&timeInfo);
+ std::ostringstream timeStr;
+ timeStr << localTime->tm_hour << "." << localTime->tm_min << "." << localTime->tm_sec;
+ m_target->write(timeStr.str(), level, str.str());
+ }
+}
+
+auto simLogger() -> Logger &
+{
+ static Logger logger;
+ return logger;
+}
\ No newline at end of file
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * 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.
+ *
+ ******************************************************************/
+
+/**
+ * @file simulator_logger.h
+ *
+ * @brief This file provides the interface for logging messages to different targets (console/file).
+ */
+
+#ifndef SIMULATOR_LOGGER_H_
+#define SIMULATOR_LOGGER_H_
+
+#include <iostream>
+#include <memory>
+
+class ILogger
+{
+ public:
+ enum Level
+ {
+ INFO = 0,
+ DEBUG,
+ WARNING,
+ ERROR
+ };
+
+ static const char *getString(Level level)
+ {
+ switch (level)
+ {
+ case Level::INFO: return "INFO";
+ case Level::DEBUG: return "DEBUG";
+ case Level::WARNING: return "WARNING";
+ case Level::ERROR: return "ERROR";
+ default: return "UNKNOWN";
+ }
+ }
+
+ virtual void write(std::string, Level, std::string) = 0;
+};
+
+class Logger
+{
+ public:
+ bool setDefaultConsoleTarget();
+ bool setDefaultFileTarget(std::string &path);
+ void setCustomTarget(std::shared_ptr<ILogger> target);
+ void write(ILogger::Level level, std::ostringstream &str);
+
+ private:
+ std::shared_ptr<ILogger> m_target;
+};
+
+auto simLogger() -> Logger &;
+
+#ifndef SIM_LOG
+#define SIM_LOG(LEVEL, MSG) { \
+ simLogger().write(LEVEL, static_cast<std::ostringstream&>(std::ostringstream()<<MSG)); \
+ }
+#endif
+
+#endif
\ No newline at end of file
SimulatorResult SimulatorManager::deleteResources(const std::string &resourceType)
{
return ResourceManager::getInstance()->deleteResources(resourceType);
+}
+
+void SimulatorManager::setLogger(std::shared_ptr<ILogger> logger)
+{
+ simLogger().setCustomTarget(logger);
+}
+
+bool SimulatorManager::setDefaultConsoleLogger()
+{
+ return simLogger().setDefaultConsoleTarget();
+}
+
+bool SimulatorManager::setDefaultFileLogger(std::string &path)
+{
+ return simLogger().setDefaultFileTarget(path);
}
\ No newline at end of file