Skip to content

Commit 7bbf5e4

Browse files
Add example in code base
1 parent 63c7237 commit 7bbf5e4

13 files changed

Lines changed: 1182 additions & 0 deletions

CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,16 @@ if (WITH_FESAPI)
258258
endif (WITH_TEST)
259259
endif (WITH_FESAPI)
260260

261+
set (WITH_EXAMPLE OFF CACHE BOOL "Also builds and installs an ETP1.2 client example.")
262+
if (WITH_EXAMPLE)
263+
if (WITH_FESAPI)
264+
add_subdirectory(example/withFesapi)
265+
else ()
266+
add_subdirectory(example/withoutFesapi)
267+
endif (WITH_FESAPI)
268+
endif (WITH_EXAMPLE)
269+
270+
261271
# ============================================================================
262272
# Install Fetpapi library
263273
# ============================================================================

example/withFesapi/CMakeLists.txt

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
CMAKE_MINIMUM_REQUIRED (VERSION 3.12)
2+
3+
project (etpClient)
4+
5+
# ============================================================================
6+
# build etpClient
7+
# ============================================================================
8+
9+
# use, i.e. don't skip the full RPATH for the build tree
10+
set(CMAKE_SKIP_BUILD_RPATH FALSE)
11+
12+
# when building, don't use the install RPATH already
13+
# (but later on when installing)
14+
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
15+
16+
set(CMAKE_INSTALL_RPATH "\$ORIGIN/${CMAKE_INSTALL_LIBDIR}")
17+
18+
# add the automatically determined parts of the RPATH
19+
# which point to directories outside the build tree to the install RPATH
20+
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
21+
22+
add_executable (${PROJECT_NAME})
23+
target_sources(${PROJECT_NAME} PRIVATE
24+
${CMAKE_CURRENT_SOURCE_DIR}/etpClient.cpp)
25+
26+
target_include_directories (${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/src/)
27+
28+
add_dependencies (${PROJECT_NAME} Fetpapi)
29+
target_link_libraries (${PROJECT_NAME} PRIVATE Fetpapi)
30+
31+
target_compile_definitions(${PROJECT_NAME} PRIVATE BOOST_ALL_NO_LIB)
32+
target_link_libraries (${PROJECT_NAME} PRIVATE AVRO::AVRO ${CMAKE_THREAD_LIBS_INIT})
33+
if (DEFINED Boost_SYSTEM_LIBRARY)
34+
target_link_libraries (${PROJECT_NAME} PRIVATE ${Boost_SYSTEM_LIBRARY})
35+
endif()
36+
if (WIN32)
37+
target_link_libraries (${PROJECT_NAME} PRIVATE bcrypt.lib)
38+
endif()
39+
if (WITH_ETP_SSL)
40+
target_compile_definitions(${PROJECT_NAME} PRIVATE WITH_ETP_SSL)
41+
target_link_libraries(${PROJECT_NAME} PRIVATE OpenSSL::SSL OpenSSL::Crypto)
42+
endif ()
43+
target_link_libraries(${PROJECT_NAME} PRIVATE FESAPI::FESAPI)
44+
45+
target_include_directories(${PROJECT_NAME} SYSTEM PRIVATE ${AVRO_INCLUDE_DIR} ${Boost_INCLUDE_DIR})
46+
if (WITH_ETP_SSL)
47+
target_include_directories(${PROJECT_NAME} SYSTEM PRIVATE ${OPENSSL_INCLUDE_DIR})
48+
endif ()
49+
target_include_directories(${PROJECT_NAME} PRIVATE ${FESAPI_INCLUDE_DIR})
50+
51+
if (WIN32)
52+
set_target_properties (${PROJECT_NAME} PROPERTIES
53+
LINK_FLAGS "/INCREMENTAL:NO"
54+
RUNTIME_OUTPUT_DIRECTORY ${FETPAPI_BINARY_DIR})
55+
endif (WIN32)
56+
57+
# The value of DEBUG_POSTFIX property is initialized when the target is created to the value of the variable CMAKE_<CONFIG>_POSTFIX
58+
# except for executable targets because earlier CMake versions which did not use this variable for executables.
59+
set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
60+
61+
install (
62+
TARGETS ${PROJECT_NAME}
63+
DESTINATION ${CMAKE_INSTALL_PREFIX}
64+
)

example/withFesapi/etpClient.cpp

Lines changed: 512 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
CMAKE_MINIMUM_REQUIRED (VERSION 3.12)
2+
3+
project (etpClient)
4+
5+
# ============================================================================
6+
# build etpClient
7+
# ============================================================================
8+
9+
# use, i.e. don't skip the full RPATH for the build tree
10+
set(CMAKE_SKIP_BUILD_RPATH FALSE)
11+
12+
# when building, don't use the install RPATH already
13+
# (but later on when installing)
14+
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
15+
16+
set(CMAKE_INSTALL_RPATH "\$ORIGIN/${CMAKE_INSTALL_LIBDIR}")
17+
18+
# add the automatically determined parts of the RPATH
19+
# which point to directories outside the build tree to the install RPATH
20+
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
21+
22+
add_executable (${PROJECT_NAME})
23+
target_sources(${PROJECT_NAME} PRIVATE
24+
${CMAKE_CURRENT_SOURCE_DIR}/etpClient.cpp
25+
${CMAKE_CURRENT_SOURCE_DIR}/MyOwnCoreProtocolHandlers.cpp
26+
${CMAKE_CURRENT_SOURCE_DIR}/MyOwnCoreProtocolHandlers.h
27+
${CMAKE_CURRENT_SOURCE_DIR}/MyOwnDiscoveryProtocolHandlers.cpp
28+
${CMAKE_CURRENT_SOURCE_DIR}/MyOwnDiscoveryProtocolHandlers.h
29+
${CMAKE_CURRENT_SOURCE_DIR}/MyOwnStoreNotificationProtocolHandlers.cpp
30+
${CMAKE_CURRENT_SOURCE_DIR}/MyOwnStoreNotificationProtocolHandlers.h
31+
${CMAKE_CURRENT_SOURCE_DIR}/MyOwnStoreProtocolHandlers.cpp
32+
${CMAKE_CURRENT_SOURCE_DIR}/MyOwnStoreProtocolHandlers.h)
33+
34+
target_include_directories (${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/src/)
35+
36+
add_dependencies (${PROJECT_NAME} Fetpapi)
37+
target_link_libraries (${PROJECT_NAME} PRIVATE Fetpapi)
38+
39+
target_compile_definitions(${PROJECT_NAME} PRIVATE BOOST_ALL_NO_LIB)
40+
target_link_libraries (${PROJECT_NAME} PRIVATE AVRO::AVRO ${CMAKE_THREAD_LIBS_INIT})
41+
if (DEFINED Boost_SYSTEM_LIBRARY)
42+
target_link_libraries (${PROJECT_NAME} PRIVATE ${Boost_SYSTEM_LIBRARY})
43+
endif()
44+
if (WIN32)
45+
target_link_libraries (${PROJECT_NAME} PRIVATE bcrypt.lib)
46+
endif()
47+
if (WITH_ETP_SSL)
48+
target_compile_definitions(${PROJECT_NAME} PRIVATE WITH_ETP_SSL)
49+
target_link_libraries(${PROJECT_NAME} PRIVATE OpenSSL::SSL OpenSSL::Crypto)
50+
endif ()
51+
52+
target_include_directories(${PROJECT_NAME} SYSTEM PRIVATE ${AVRO_INCLUDE_DIR} ${Boost_INCLUDE_DIR})
53+
if (WITH_ETP_SSL)
54+
target_include_directories(${PROJECT_NAME} SYSTEM PRIVATE ${OPENSSL_INCLUDE_DIR})
55+
endif ()
56+
57+
if (WIN32)
58+
set_target_properties (${PROJECT_NAME} PROPERTIES
59+
LINK_FLAGS "/INCREMENTAL:NO"
60+
RUNTIME_OUTPUT_DIRECTORY ${FETPAPI_BINARY_DIR})
61+
endif (WIN32)
62+
63+
# The value of DEBUG_POSTFIX property is initialized when the target is created to the value of the variable CMAKE_<CONFIG>_POSTFIX
64+
# except for executable targets because earlier CMake versions which did not use this variable for executables.
65+
set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
66+
67+
install (
68+
TARGETS ${PROJECT_NAME}
69+
DESTINATION ${CMAKE_INSTALL_PREFIX}
70+
)
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
/*-----------------------------------------------------------------------
2+
Licensed to the Apache Software Foundation (ASF) under one
3+
or more contributor license agceements. See the NOTICE file
4+
distributed with this work for additional information
5+
regarding copyright ownership. The ASF licenses this file
6+
to you under the Apache License, Version 2.0 (the
7+
"License"; you may not use this file except in compliance
8+
with the License. You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agceed to in writing,
13+
software distributed under the License is distributed on an
14+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
KIND, either express or implied. See the License for the
16+
specific language governing permissions and limitations
17+
under the License.
18+
-----------------------------------------------------------------------*/
19+
#include "MyOwnCoreProtocolHandlers.h"
20+
21+
#include <thread>
22+
23+
#include <boost/uuid/random_generator.hpp>
24+
#include <boost/uuid/uuid_io.hpp>
25+
26+
#include "etp/EtpHelpers.h"
27+
#include "etp/PlainClientSession.h"
28+
29+
#include "MyOwnDiscoveryProtocolHandlers.h"
30+
#include "MyOwnStoreProtocolHandlers.h"
31+
32+
void printHelp()
33+
{
34+
std::cout << "List of available commands :" << std::endl;
35+
std::cout << "\tPing" << std::endl << "\t\tPing the server" << std::endl << std::endl;
36+
std::cout << "\tList" << std::endl << "\t\tList the objects which have been got from ETP to the in-memory epc" << std::endl << std::endl;
37+
std::cout << "\tPutXmldAndHdfAtOnce" << std::endl << "\t\tPut a dummy point set representation to the store sending XML and HDF5 points at once." << std::endl << std::endl;
38+
std::cout << "\tGetResources URI scope(default self) depth(default 1) countObjects(true or false, default is true) dataTypeFilter,dataTypeFilter,...(default noFilter)" << std::endl << std::endl;
39+
std::cout << "\tGetDataObjects dataObjectURI,dataObjectURI,..." << std::endl << "\t\tGet the objects from an ETP store and store them into the in memory epc (only create partial TARGET relationships, not any SOURCE relationships)" << std::endl << std::endl;
40+
std::cout << "\tGetXYZPoints URI" << std::endl << "\t\tGet the XYZ points of a rep from store and print some of them." << std::endl << std::endl;
41+
std::cout << "\tPutDataObject UUID" << std::endl << "\t\tPut the XML part of a dataobject which is on the client side (use \"Load\" command to laod some dataobjects on client side) to the store" << std::endl << std::endl;
42+
std::cout << "\tGetDataArray epcExternalPartURI datasetPathInEpcExternalPart" << std::endl << "\t\tGet the numerical values from a dataset included in an EpcExternalPart over ETP." << std::endl << std::endl;
43+
std::cout << "\tPutDataArray epcExternalPartURI datasetPathInEpcExternalPart" << std::endl << "\t\tPut a dummy {0,1,2,3,4,5,6,7,8,9} integer array in a particular store epcExternalPartURI at a particular dataset path" << std::endl << std::endl;
44+
std::cout << "\tSubscribeNotif URI scope(default self) depth(default 1) receiveXML(true or false, default is true) dataTypeFilter,dataTypeFilter,...(default noFilter)" << std::endl << "\t\tSubscribe to notifications." << std::endl << std::endl;
45+
std::cout << "\tLoad epcDocument" << std::endl << "\t\tLoad an EPC document into the DataObjectRepository." << std::endl << std::endl;
46+
std::cout << "\tSetVerbosity 0or1" << std::endl << "\t\tSet the sesion verbosity to true or false" << std::endl << std::endl;
47+
std::cout << "\tquit" << std::endl << "\t\tQuit the session." << std::endl << std::endl;
48+
}
49+
50+
void askUser(ETP_NS::AbstractSession* session)
51+
{
52+
std::string buffer;
53+
54+
std::cout << "What is your command (\"quit\" for closing connection)?" << std::endl;
55+
std::string command;
56+
while (command != "quit")
57+
{
58+
if (session->isEtpSessionClosed()) {
59+
command = "quit";
60+
}
61+
else {
62+
std::getline(std::cin, command);
63+
}
64+
auto commandTokens = tokenize(command, ' ');
65+
66+
if (commandTokens.empty()) {
67+
printHelp();
68+
continue;
69+
}
70+
if (commandTokens[0] == "quit") {
71+
continue;
72+
}
73+
74+
if (commandTokens[0] == "GetResources") {
75+
Energistics::Etp::v12::Protocol::Discovery::GetResources mb;
76+
mb.context.uri = commandTokens[1];
77+
mb.scope = Energistics::Etp::v12::Datatypes::Object::ContextScopeKind::self;
78+
mb.context.depth = 1;
79+
mb.context.navigableEdges = Energistics::Etp::v12::Datatypes::Object::RelationshipKind::Primary;
80+
mb.countObjects = true;
81+
82+
if (commandTokens.size() > 2) {
83+
if (commandTokens[2] == "self")
84+
mb.scope = Energistics::Etp::v12::Datatypes::Object::ContextScopeKind::self;
85+
else if (commandTokens[2] == "sources")
86+
mb.scope = Energistics::Etp::v12::Datatypes::Object::ContextScopeKind::sources;
87+
else if (commandTokens[2] == "sourcesOrSelf")
88+
mb.scope = Energistics::Etp::v12::Datatypes::Object::ContextScopeKind::sourcesOrSelf;
89+
else if (commandTokens[2] == "targets")
90+
mb.scope = Energistics::Etp::v12::Datatypes::Object::ContextScopeKind::targets;
91+
else if (commandTokens[2] == "targetsOrSelf")
92+
mb.scope = Energistics::Etp::v12::Datatypes::Object::ContextScopeKind::targetsOrSelf;
93+
94+
if (commandTokens.size() > 3) {
95+
mb.context.depth = std::stoi(commandTokens[3]);
96+
97+
if (commandTokens.size() > 4) {
98+
if (commandTokens[4] == "false" || commandTokens[4] == "False" || commandTokens[4] == "FALSE") {
99+
mb.countObjects = false;
100+
}
101+
102+
if (commandTokens.size() > 5) {
103+
mb.context.dataObjectTypes = tokenize(commandTokens[5], ',');
104+
}
105+
}
106+
}
107+
}
108+
109+
session->send(mb, 0, 0x02);
110+
111+
continue;
112+
}
113+
else if (commandTokens[0] == "SetVerbosity") {
114+
if (commandTokens[1].size() == 1 && commandTokens[1][0] == '1') {
115+
std::cout << "Set the verbosity ON" << std::endl;
116+
session->setVerbose(true);
117+
}
118+
else {
119+
std::cout << "Set the verbosity OFF" << std::endl;
120+
}
121+
session->setVerbose(commandTokens[1].size() == 1 && commandTokens[1][0] == '1');
122+
}
123+
else if (commandTokens[0] == "GetDataObjects") {
124+
Energistics::Etp::v12::Protocol::Store::GetDataObjects getO;
125+
std::vector<std::string> tokens = tokenize(commandTokens[1], ',');
126+
std::map<std::string, std::string> tokenMaps;
127+
for (size_t i = 0; i < tokens.size(); ++i) {
128+
tokenMaps[std::to_string(i)] = tokens[i];
129+
}
130+
getO.uris = tokenMaps;
131+
session->send(getO, 0, 0x02);
132+
}
133+
else if (commandTokens[0] == "SubscribeNotif") {
134+
Energistics::Etp::v12::Protocol::StoreNotification::SubscribeNotifications mb;
135+
Energistics::Etp::v12::Datatypes::Object::SubscriptionInfo subscriptionInfo;
136+
subscriptionInfo.context.uri = commandTokens[1];
137+
subscriptionInfo.scope = Energistics::Etp::v12::Datatypes::Object::ContextScopeKind::self;
138+
subscriptionInfo.context.depth = 1;
139+
boost::uuids::random_generator gen;
140+
boost::uuids::uuid uuid = gen();
141+
std::move(std::begin(uuid.data), std::end(uuid.data), subscriptionInfo.requestUuid.array.begin());
142+
143+
if (commandTokens.size() > 2) {
144+
if (commandTokens[2] == "self")
145+
subscriptionInfo.scope = Energistics::Etp::v12::Datatypes::Object::ContextScopeKind::self;
146+
else if (commandTokens[2] == "sources")
147+
subscriptionInfo.scope = Energistics::Etp::v12::Datatypes::Object::ContextScopeKind::sources;
148+
else if (commandTokens[2] == "sourcesOrSelf")
149+
subscriptionInfo.scope = Energistics::Etp::v12::Datatypes::Object::ContextScopeKind::sourcesOrSelf;
150+
else if (commandTokens[2] == "targets")
151+
subscriptionInfo.scope = Energistics::Etp::v12::Datatypes::Object::ContextScopeKind::targets;
152+
else if (commandTokens[2] == "targetsOrSelf")
153+
subscriptionInfo.scope = Energistics::Etp::v12::Datatypes::Object::ContextScopeKind::targetsOrSelf;
154+
155+
if (commandTokens.size() > 3) {
156+
subscriptionInfo.context.depth = std::stoi(commandTokens[3]);
157+
158+
if (commandTokens.size() > 4) {
159+
subscriptionInfo.includeObjectData = commandTokens[4] == "true";
160+
161+
if (commandTokens.size() > 5) {
162+
subscriptionInfo.context.dataObjectTypes = tokenize(commandTokens[5], ',');
163+
}
164+
}
165+
}
166+
}
167+
168+
mb.request["0"] = subscriptionInfo;
169+
170+
session->send(mb, 0, 0x02);
171+
172+
continue;
173+
}
174+
175+
if (commandTokens.size() == 1) {
176+
if (commandTokens[0] == "Ping") {
177+
Energistics::Etp::v12::Protocol::Core::Ping ping;
178+
ping.currentDateTime = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
179+
session->send(ping, 0, 0x02); // 0x10 requires Acknowledge from the store
180+
std::cout << "PING at " << ping.currentDateTime << std::endl;
181+
}
182+
}
183+
else if (commandTokens.size() == 3) {
184+
if (commandTokens[0] == "GetDataArray") {
185+
Energistics::Etp::v12::Protocol::DataArray::GetDataArrays gda;
186+
gda.dataArrays["0"].uri = commandTokens[1];
187+
gda.dataArrays["0"].pathInResource = commandTokens[2];
188+
std::cout << gda.dataArrays["0"].pathInResource << std::endl;
189+
session->send(gda);
190+
}
191+
else if (commandTokens[0] == "PutDataArray") {
192+
Energistics::Etp::v12::Protocol::DataArray::PutDataArrays pda;
193+
pda.dataArrays["0"].uid.uri = commandTokens[1];
194+
pda.dataArrays["0"].uid.pathInResource = commandTokens[2];
195+
196+
std::vector<int64_t> dimensions = { 10 };
197+
pda.dataArrays["0"].array.dimensions = dimensions;
198+
199+
Energistics::Etp::v12::Datatypes::AnyArray data;
200+
Energistics::Etp::v12::Datatypes::ArrayOfInt arrayOfInt;
201+
arrayOfInt.values = { 0,1,2,3,4,5,6,7,8,9 };
202+
data.item.set_ArrayOfInt(arrayOfInt);
203+
pda.dataArrays["0"].array.data = data;
204+
205+
session->send(pda, 0, 0x02);
206+
}
207+
}
208+
}
209+
210+
session->close();
211+
}
212+
213+
void MyOwnCoreProtocolHandlers::on_OpenSession(const Energistics::Etp::v12::Protocol::Core::OpenSession & os, int64_t correlationId)
214+
{
215+
// Ask the user about what he wants to do on another thread
216+
// The main thread is on reading mode
217+
std::thread askUserThread(askUser, session);
218+
askUserThread.detach(); // Detach the thread since we don't want it to be a blocking one.
219+
}

0 commit comments

Comments
 (0)