diff --git a/.gitignore b/.gitignore index dd773030f671232561983bd8fea8adc00c329cc2..00f9ccbb01e2f62927b9f62fe1b876c0d2e2202a 100644 --- a/.gitignore +++ b/.gitignore @@ -6,14 +6,19 @@ *.jnilib *.gch +#Development +.DS_Store #for gradle builds build/* .gradle/* +libs/* #for visual-studio-code bin/* .vscode/* +.devcontainer/* +*.code-workspace #for leiningen builds .lein* diff --git a/Makefile b/Makefile index e8cbf7590e830c333ddcdd06cc74d61946a9008b..074cdd78bd2abc77d084f00ca07f7cfe6d7ef4d4 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,107 @@ -.PHONY : install +#Primary Makefile for the MessageAPI package. +# +#This Makefile currently controls the build for: +# +#1. Java-core build, test, and subsequent artifact (versioned uberjar + install script) tar packaging +#2. C/C++ API shared library build, test, and subsequent artifact (versioned .so + current full source/header set + install script) +#tar packaging +#3. Java API documentation artifact (html documents as tar) packaging +# +#Note that the package itself has an install.sh bash script ($PKG/scripts/install/package/install.sh) +#that controls installation of specific libraries for any logged in user on the NCEI mission network. -all: install +#Library Name and Version +LIBRARY_NAME=messageapi +MAJOR_VERSION=1 +MINOR_VERSION=0 +PATCH_VERSION=0 +EXTENSION_VERSION=all + +#Root Path Computation +PROJECT_ROOT:=$(PWD) + +#Java Related Paths +JAR_SRC_DIR=$(PROJECT_ROOT)/build/libs +SRC_JAR=$(LIBRARY_NAME)-$(MAJOR_VERSION).$(MINOR_VERSION).$(PATCH_VERSION)-$(EXTENSION_VERSION).jar +JAVA_ARTIFACT_DIR=$(PROJECT_ROOT)/dist/artifacts/java/$(LIBRARY_NAME)_$(MAJOR_VERSION)_$(MINOR_VERSION)_$(PATCH_VERSION) +TARGET_JAR=messageapi-core-$(MAJOR_VERSION).$(MINOR_VERSION).$(PATCH_VERSION).jar +JAR_INSTALL_SCRIPT=$(PROJECT_ROOT)/scripts/install/java/main/install.sh + +DOCS_SRC_DIR=$(PROJECT_ROOT)/build/docs/groovydoc +API_DOCS_DIR=$(PROJECT_ROOT)/dist/docs/api + +#C/C++ Related Paths +C_MAIN_BUILD_DIR=$(PROJECT_ROOT)/scripts/build/c/main +C_TEST_BUILD_DIR=$(PROJECT_ROOT)/scripts/build/c/test + +TEST_RESOURCE_DIR=$(PROJECT_ROOT)/libs + +run-native-tests: export LD_LIBRARY_PATH = $(JAVA_HOME)/lib/jli:$(JAVA_HOME)/lib/server +run-native-tests: export CLASSPATH = $(TEST_RESOURCE_DIR)/test/java/jars/$(SRC_JAR) + +.PHONY: build-c_cpp prep-java build-java dist-java run-native-tests copy-docs cleanup + +all: build-c_cpp prep-java build-java dist-java copy-docs run-native-tests cleanup + +build-c_cpp: + @echo "Building the shared library for C/C++ native sessions and the distributable native C artifacts." + @make -C $(C_MAIN_BUILD_DIR) + @echo "Building C/C++ binary for native transformation tests." + @make -C $(C_TEST_BUILD_DIR)/transformation + @echo "Building C/C++ binary for native endpoint tests." + @make -C $(C_TEST_BUILD_DIR)/endpoint + @echo "Building C/C++ binary for native session tests." + @make -C $(C_TEST_BUILD_DIR)/session + @echo "Finished all C/C++ related build tasks." + +cleanup: + @echo "Cleaning up test resources." + @rm -rf $(TEST_RESOURCE_DIR) + +prep-java: + @echo "Cleaning any residual Java artifacts." + @rm -rf $(JAVA_ARTIFACT_DIR) + @rm -rf $(API_DOCS_DIR) + @echo "Java ready for build." + +build-java: + @echo "Running java gradle build and tests for MessageAPI." + @gradle + @mkdir -p $(TEST_RESOURCE_DIR)/test/java/jars + @cp $(PROJECT_ROOT)/build/libs/$(SRC_JAR) $(TEST_RESOURCE_DIR)/test/java/jars + @echo "Finished java gradle build and tests for MessageAPI." + +dist-java: + @echo "Creating distributable Java artifacts." + @cp $(JAR_SRC_DIR)/$(SRC_JAR) $(JAR_SRC_DIR)/$(TARGET_JAR) + @cp $(JAR_INSTALL_SCRIPT) $(JAR_SRC_DIR) + @mkdir -p $(JAVA_ARTIFACT_DIR) + @-cd $(JAR_SRC_DIR) && tar -cf $(LIBRARY_NAME).tar $(TARGET_JAR) install.sh + @-cd $(JAR_SRC_DIR) && mv $(LIBRARY_NAME).tar $(JAVA_ARTIFACT_DIR) + +copy-docs: + @echo "Copying API docs for distribution." + @mkdir -p $(API_DOCS_DIR) + @-cd $(DOCS_SRC_DIR) && tar -cf $(API_DOCS_DIR)/messageapi_docs.tar * + @echo "Finished copying API docs for distribution." + +run-native-tests: + @echo "Running native C/C++ session test." + @-cd $(TEST_RESOURCE_DIR)/test/c/session && ./SessionDemo.bin + @echo "Finished running native C/C++ session test." + +install-k3: + @echo "Installing package to system for current user." + @wget https://k3.cicsnc.org/rberkheimer/messageapi/-/raw/mac-develop/scripts/install/package/install_k3.sh?inline=false --no-check-certificate -O install_k3.sh + @chmod +x install_k3.sh + @./install_k3.sh "C_CPP" + @rm install_k3.sh + @echo "Finished installing package, validate ~./bashrc and env vars for success." install: - echo "Running gradle build for MessageAPI." - ${GRADLE} - echo "Finished gradle build for MessageAPI." + @echo "Installing package to system for current user." + @wget https://git.ncei.noaa.gov/sesb/sscs/messageapi/-/raw/master/scripts/install/package/install.sh?inline=false --no-check-certificate -O install.sh + @chmod +x install.sh + @./install.sh "C_CPP" + @rm install.sh + @echo "Finished installing package, validate ~/.bashrc and env vars for success." \ No newline at end of file diff --git a/README.md b/README.md index 470a552b22f6ce699a087196a11497e2d209c6e8..39038814e16bc809c969470e135c4f2266e38fd6 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,21 @@ ## Version -**0.9.0** (Pre-Release) +**0.9.10** (Pre-Release) -MessageAPI uses [Semantic Versioning 2.0.0](https://semver.org/) as its versioning strategy. The first official version will be released upon the implementation of the C native API. Subsequent minor versions will release the fortran, python, IDL, and R APIs. +MessageAPI uses [Semantic Versioning 2.0.0](https://semver.org/) as its versioning strategy. The first official version will be released upon the implementation of the C native API and validation of the Java core. Subsequent minor versions will release the Fortran, Python, R, and IDL APIs, and Bash CLI. + +## API Docs + +Use of this package is described throughout this README through design discussions and examples. Once familiar with the general use case of the package, more complete [API Docs](./dist/docs/api/messageapi_docs.tar) can be downloaded and referenced (open index.html after extracting the tar). + +## Executive Summary + +MessageAPI was built to promote and improve the long-term sustainability and enterprise-scale innovative capabilities of large research and operations organizations like NCEI, NESDIS, and NOAA. A simple and static (never changing) language-level API provided in multiple languages together with a completely configurable process configuration allows fast augmentation of legacy code to use evolutionary features, allows teams to reuse existing algorithms, and ensures that code-level details don't have to change as interface-level technologies evolve. The idea is to provide a capability so that Java/JVM, C/C++, Fortran, Python, R, and IDL programmers can continue to use their own preferred languages and technologies to do research and development, while ensuring that they can continue to evolve along with emerging organizational requirements and trends, without making code changes. + +MessageAPI has a small multi-language core that is easily installed on mission systems as a non-root user using the mature build system; allows whitelisting of executable resources and configuration-level exposition to maintain visible security; and provides a thread-safe, asynchronous, stream and batch capable data model to build composable, scalable, and orchestrated computational processes. + +MessageAPI abstracts container factoring, container classification, conditional filtering, stateless transformation, and bidirectional endpoint processing into JSON configuration. This allows legacy code to be refactored or restructures in a fine-grained or large-scale way. Even the core parts of MessageAPI itself are configurable through JSON manifest, allowing the system to be customized to various use cases. ## Overview @@ -67,8 +79,6 @@ Figure 1 below illustrates the layout of a Session - how MessageAPI structures a Everything that passes data in MessageAPI consumes and produces the same object type - the record. The manifests are used in code by creating a session based on them - and then using a stable API to create a request, add records, set field and/or condition values, and then submit, which immediately returns an async response. The response will hold its own records and rejections, and eventually get an 'isComplete' flag. That's the entirety of the API surface. Everything else depends on the Manifest. -All of these actions are - MessageAPI is designed to be capable of passing any message content - objects, database entries, emails, etc., to/through anywhere - database tables, inboxes, s3 buckets, ftp, smtp, kafka, files, directories etc. The benefits of using MessageAPI are its extreme schema flexibility, potential for tool decoupling and transport optimization, API standardization across all messaging, and self documentation through an information model. @@ -133,7 +143,7 @@ The following is an example of a DefaultSession manifest: } ``` -The general pattern in a manifest is to declare a key with the class as the plugin, and then provide another map that holds constructor parameters. The specification for MessageAPI consists of +The general pattern in a manifest is to declare a key with the class as the plugin, and then provide another map that holds constructor parameters. The specification for MessageAPI consists of: - A **Session**, which holds the primary **Schema**, **Container**, and **Protocol** dimensions - A **Schema**, which defines all the **Fields** and **Conditions** (optional) a user will interact with for each **Record** @@ -164,10 +174,10 @@ Note that both Conditions and Transformations specify 'factories'. These factori "fields": ["file-path"], "conditions": ["is-relative-path"]}], "transformations": [{"id": "trans-1", - "operator": "fix-relative-paths", - "constructor": {"transform-key": "file-collection"}, - "records": {"file-collection": {"COLLECTION": "coll-1"}}, - "fields": ["file-path"]}], + "operator": "gov.noaa.messageapi.test.transformations.FixRelativePathsTransformation", + "constructor": {"transform-key": "file-collection", + "fields": ["file-path"]}, + "records": {"file-collection": {"COLLECTION": "coll-1"}}}], "connections": [{"id": "conn-1", "transformations": ["trans-1"], "constructor": {"file-fields": "file-path"}, @@ -283,7 +293,7 @@ In the provided implementation, the types understood by the system (for use by c ###### Condition Sets -Conditions can be set on fields that qualify records when passed in, serving as a potentially powerful filtering tool. In the provided default plugin, conditions must specify at least a unique id, a type, and an operator. Conditions that are to be used in filtering must be valued on individual records. Conditions are also provided on a whole-request basis - to be used in containerization of records. In this case, conditions can be given values when +Conditions can be set on fields that qualify records when passed in, serving as a potentially powerful dynamic filtering tool. In the provided default plugin, conditions must specify at least a unique id, a type, and an operator. Conditions that are to be used in filtering must be valued on individual records. Conditions are also provided on a whole-request basis - to be used in containerization of records. In this case, conditions can be given values on the request itself, to be used for parsing into collection-containers by applying to every potential record that is declared as part of a collection set. There are two condition types in the provided implementation - composite and comparison. @@ -419,7 +429,7 @@ There are three types of container groupings provided by the default MessageAPI - **Transformations** are computational containers. They are an optional component of MessageAPI. Transformations act as instances of immutable functions that can hold global, configurable constructor/initialization parameters, use other arbitrary named containers as arguments in a process function, return a list of records, and list the fields that each record will provide in a 'fields' map entry. Transformations are always immutable, executed lazily (only when called in an Endpoint), and always operate on and produce lists of records. -The 'records' entry on the Transformation map itself holds a map of named parameter keys that correspond to values describing what type of container and the id of that container to use as that particular input. For example, in the following Transformation map, the first Transformation is called 'join-test'. The Transformation has an operator of 'join', which corresponds to a java class in the TransformationFactory listed in the Session manifest. This Transformation provides a constructor map containing two keys, 'join_field' and 'collection_field', both which specify constants that are set in the Transformation when it is initialized. +The 'records' entry on the Transformation map itself holds a map of named parameter keys that correspond to values describing what type of container and the id of that container to use as that particular input. For example, in the following Transformation map, the first Transformation is called 'join-test'. The Transformation has an operator of the fully qualified join Class listed in the Session manifest. This Transformation provides a constructor map containing two keys, 'join_field' and 'collection_field', both which specify constants that are set in the Transformation when it is initialized. The 'join-test' Transformation defines three parameters in its process method map - 'parent', 'child', and 'other'. Each of these corresponds to a different container - when used in the Transformation, the 'parent' parameter will provide a list of all records contained by the 'namespace=condition-test' classifier; the 'child' parameter will provide a list of records contained by the 'mix-and-match' collection; and the 'other' parameter contains a special case - the UUID - which will provide every collection for a given UUID, and map the Transformation to every UUID, and all returned records for every UUID in this Transformation will be merged on return. The use of UUID as a Transformation record parameter is a special case, and due to its mapping ability, limits its use to once per Transformation. @@ -434,21 +444,21 @@ It is the view of the package authors that Transformations hold computational ta "transformations": [ { "id": "join-test", - "operator": "join", + "operator": "gov.noaa.messageapi.transformations.joins.StringFieldJoin", "constructor": {"join_field": "key", - "collection_field": "mix-and-match"}, + "collection_field": "mix-and-match", + "fields": ["key", "record", "filename", "type", "mix-and-match"]}, "records": {"parent": {"CLASSIFIER": ["namespace", "condition-test"]}, "child": {"COLLECTION": "mix-and-match"}, - "other": "UUID"}, - "fields": ["key", "record", "filename", "type", "mix-and-match"] + "other": "UUID"} }, { "id": "reduce-test", - "operator": "reduce-sum", + "operator": "gov.noaa.messageapi.transformations.reductions.ReduceTransformation", "constructor": {"reduce-field": "mix-and-match", - "reduce-target": "mix-and-match-reduction"}, - "records": {"reduce-list" : {"TRANSFORMATION": "join-test"}}, - "fields": ["key", "mix-and-match-reduction"] + "reduce-target": "mix-and-match-reduction", + "fields": ["key", "mix-and-match-reduction"]}, + "records": {"reduce-list" : {"TRANSFORMATION": "join-test"}} }] } ``` @@ -595,9 +605,9 @@ Once the records are set, call submit on the request. This submission immediatel ```java import gov.noaa.messageapi.interfaces.IResponse; -IResponse response = request.submit(); \\asynchronous, returns immediately +IResponse response = request.submit(); //asynchronous, returns immediately -System.out.println(response.isComplete()); \\would initially return 'False' +System.out.println(response.isComplete()); //would initially return 'False' ``` When complete, the IResponse will flip isComplete() to true, and will have available IRecords and IRejections. @@ -710,7 +720,26 @@ Because requests contain a copy of the session variables which created them, the ##### Package Use -When installed from source or acquired through repository, the MessageAPI-all.jar contains all dependencies required to run standalone. Because of the way MessageAPI handles Session bootstrapping, it is not required to bundle the MessageAPI core with user ConditionFactories, TransformationFactories, or Endpoints. As long as these are made available to MessageAPI on the Java classpath at Session creation, Sessions will be able to use them. This design makes it easier to automate things like creating K8s pods of certain session types. +###### Prebuilt Resources +The package can be retrieved and used as a precompiled set of artifacts packaged as tar files. There are currently tar files for the core Java library and the precompiled C/C++ native library (compiled using the RHEL7 UBI, which is freely available from Redhat and compatible with Openshift). Each tar comes with an install.sh file that will install the relevant component for the current user. This means that for the Java package, the MessageAPI jar will be installed to a user directory, which will be added to the PATH and the Jar will be added to the CLASSPATH (if not already installed). The C library will add the shared library to the PATH and set up environment variables for use of the packaged header and source files. No root privileges are required to install or use the precompiled package resources. There is a central install script that will unpackage and install all components and relevant environment variables for you, for either "C_CPP" or "CORE". See below for instructions. + +To install on a mission system at NCEI, do the following: + +1. Make sure you are logged into the NCEI gitlab in the usual way. If you are logged, in, you will be able to access repositories. +2. Copy/paste the following five lines in a terminal one by one, hitting enter after each, for the user that will be using MessageAPI: + - wget https://git.ncei.noaa.gov/sesb/sscs/messageapi/-/raw/master/scripts/install/package/install.sh?inline=false --no-check-certificate -O install.sh + - chmod +x install.sh + - ./install.sh "C_CPP" + - rm install.sh + - source ~/.bashrc +3. You now have access to all MessageAPI resources needed to build and run MessageAPI dependent software, including build templates, headers, and shared libraries. Convenient environment variables have also been set up in the bashrc (which are also used by build templates) - use a cat ~/.bashrc to see which ones are available. + +###### Building From Source +When acquired through repository, the package can be built from source in order to run included tests. A Dockerfile for building the package is included in the resources/docker directory - this Dockerfile is based on the RHEL7 UBI and contains all necessary packages needed to build the MessageAPI system. This file can be used as-is or as a reference to guide what resources and conditions are necessary. + +Important to note - because of the way MessageAPI handles Session bootstrapping, it is not required or even desired to bundle the MessageAPI core with user classes. As long as these are made available to MessageAPI on the Java classpath at Session creation within a JAR, Sessions will be able to use them. This design makes it easier to automate things like creating K8s pods of certain session types. + +Also important to note for native Session use - MessageAPI Core and any user classes must be included in a JAR (not necessarily the same JAR), and these JARS must be explicitly listed on the Java CLASSPATH (they cannot be included using directory wildcard expansions). This is due to how the JVM is created during session spin-up. See the CLASSPATH variable in ~/.bashrc with the #messageapi_core_set_classpath comment to see how the core is included on the classpath. To include user class-containing JARS, just add them in a similar way. If desired or needed, MessageAPI can be bundled into other JARS or packages containing user Factories and Endpoints for portability, performance, security, or other reasons. @@ -720,15 +749,15 @@ If desired or needed, MessageAPI can be bundled into other JARS or packages cont ## Installation and Deployment -At the time of this writing, MessageAPI (0.0.10-PRERELEASE) was built using OpenJDK 11.0.3 with gradle 5.4.1. Older JDK versions are not guaranteed to work. +At the time of this writing, MessageAPI was built and tested using OpenJDK 1.8 as well as 11.0.3 with gradle 5.4.1. Older JDK versions are not guaranteed to work. There was a breaking change between older versions of gradle and the 5 series, and a relative path resolution method was updated to accommodate this change. If building from scratch, the gradle version must be upgraded to 5.4.1+. -Once these two system dependencies are met, this package can be run with tests by running 'gradle' from the package root. +Once these two system dependencies are met, this package can be run with tests by running 'make' from the package root. ```Makefile -gradle +make ``` If tests complete successfully, gradle will install MessageAPI to the local repository as an UberJAR on disk (usually in ~/.m2). UberJARs contain all of their dependencies, so the package can be run, for example, in a Java-enabled JupyterNotebook Kernel. Gradle will also create the javadocs (groovydocs) in the build directory ($PACKAGE/build/docs/groovydoc/index.html). @@ -740,12 +769,17 @@ Other dependencies are installed for the purposes of running tests, including Gr ## Developer Guide -In addition to reading issue, tag, and push history in the git repository, developers may refer to the more detailed [developer work log history](./DeveloperWorkLog.md). This document outlines features currently and previously under focus, providing motivations, descriptions, design behaviors, and justifications. +In addition to reading issue, tag, and push history in the git repository, developers may refer to the more detailed [developer work log history](./docs/development/DeveloperWorkLog.md). This document outlines features currently and previously under focus, providing motivations, descriptions, design behaviors, and justifications. + +### Bugs and Feature Requests + +The package is in current, active development, and as such, some bugs or desired features are expected. Either type of note can be sent on to ryan.berkheimer@noaa.gov. + + +### Caveats and Gotchas -### Bugs +Important to note for native (non-JVM) Session use - MessageAPI Core and any user classes must be included in a JAR (not necessarily the same JAR), and these JARS must be explicitly listed on the Java CLASSPATH (they cannot be included using directory wildcard expansions). This is due to how the JVM is created during session spin-up. See the CLASSPATH variable in ~/.bashrc with the #messageapi_core_set_classpath comment (after installing the package) to see how the core is included on the classpath. To include user class-containing JARS, just add them in a similar way. -The package is in current, active development. -All bugs encountered should be reported to ryan.berkheimer@noaa.gov. ## License diff --git a/build.gradle b/build.gradle index 895146ddf47c3bb34b45d70bec44fa83275e359f..7cf0ea442a6436f5fc995f248882ccfeff1d536a 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ plugins { id 'groovy' id 'maven-publish' id 'java' - id 'com.github.johnrengelman.shadow' version '5.0.0' + id 'com.github.johnrengelman.shadow' version '5.2.0' } shadowJar { @@ -15,6 +15,7 @@ shadowJar { } } + publishing { publications { maven(MavenPublication) { @@ -39,21 +40,27 @@ publishing { sourceCompatibility = "${javaVersion}" targetCompatibility = "${javaVersion}" -defaultTasks 'clean', 'rebuild','uploadShadow', 'publishToMavenLocal', 'groovydoc' +defaultTasks 'clean', 'rebuild', 'uploadShadow', 'publishToMavenLocal', 'groovydoc' + + +configurations { + // configuration that holds jars to include in the jar + directDeps +} repositories { mavenCentral() jcenter() } - dependencies { - compile ("com.googlecode.json-simple:json-simple:${jsonSimpleVersion}", - "commons-net:commons-net:${apacheCommonsNetVersion}", + directDeps ("com.googlecode.json-simple:json-simple:${jsonSimpleVersion}") + compile ("commons-net:commons-net:${apacheCommonsNetVersion}", "org.codehaus.groovy:groovy-all:${groovyVersion}") testCompile ("org.slf4j:slf4j-simple:${slf4jVersion}", "org.spockframework:spock-core:${spockVersion}") testRuntime ("com.athaydes:spock-reports:${spockReportsVersion}") + configurations.compile.extendsFrom(configurations.directDeps) } jar { @@ -61,6 +68,11 @@ jar { attributes 'Implementation-Title': 'MessageAPI', 'Implementation-Version': "${messageApiVersion}" } + /*from { + configurations.directDeps.collect { + it.isDirectory() && it.getPath().contains("json-simple") ? it : project.logger.lifecycle(it.getPath()) + } + }*/ } sourceSets { diff --git a/dist/artifacts/c/messageapi_1_0_0/messageapi.tar b/dist/artifacts/c/messageapi_1_0_0/messageapi.tar new file mode 100644 index 0000000000000000000000000000000000000000..6d95b9312b7e97ace71ffac398f0a9b726d3b174 Binary files /dev/null and b/dist/artifacts/c/messageapi_1_0_0/messageapi.tar differ diff --git a/dist/artifacts/java/messageapi_1_0_0/messageapi.tar b/dist/artifacts/java/messageapi_1_0_0/messageapi.tar new file mode 100644 index 0000000000000000000000000000000000000000..a5ec6b56874772c0e0061cfc960932099d0142b4 Binary files /dev/null and b/dist/artifacts/java/messageapi_1_0_0/messageapi.tar differ diff --git a/dist/docs/api/messageapi_docs.tar b/dist/docs/api/messageapi_docs.tar new file mode 100644 index 0000000000000000000000000000000000000000..955c730f9cbf3edb88ae4b21d2413970e442d9ec Binary files /dev/null and b/dist/docs/api/messageapi_docs.tar differ diff --git a/DeveloperWorkLog.md b/dist/docs/development/DeveloperWorkLog.md similarity index 98% rename from DeveloperWorkLog.md rename to dist/docs/development/DeveloperWorkLog.md index e568bd69e5b58d74205d392b08b43349deedc4d7..f8383ae579c07202c02ba81cbfe70341edc541bc 100644 --- a/DeveloperWorkLog.md +++ b/dist/docs/development/DeveloperWorkLog.md @@ -9,19 +9,24 @@ with current development, and should be supplemental to the repository record. This work log is also useful as a supplemental documentation for end users of the package - features are described and contextualized with as much detail as possible. -## Future Work +## Future Work in MessageAPI Core - Fortran API - Python API -- Split Publish/Consumer Sessions -- Example Endpoints (Email, Directory, Kafka) +- R API +- IDL API +- Shell Utilities ## Current Focus ### C API -#### Status - In Progress +#### Status - In Resolution +07/15/2020 +At this stage - the entire API is complete. The general structure is to have importable libs for each interface component (transformation, endpoint, session, condition) and have these libs contain access to every piece of processing logic that users might need. For each lib is associated + +06/01/2020 We are currently working on the linkage between C++ and the NativeEndpoint class. The NativeEndpoint class has been established and the majority of C structs have been created. The next challenge is to create C/C++ methods that work on these C structs, and then methods that bind to Java methods. #### Description and Goals diff --git a/gradle.properties b/gradle.properties index bcdc0f488ee4104e6c1a76e1fff33e50c0c0a8a9..eb514f2cc02fec7a799e969ed11771c1eeafdaf7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ #Software version -messageApiVersion = 0.0.10 +messageApiVersion = 1.0.0 #Dependency versions @@ -7,11 +7,11 @@ messageApiVersion = 0.0.10 #javaVersion = 11.0.3 javaVersion = 1.8 -#Utils +#Runtime Deps jsonSimpleVersion = 1.1.1 #Build -shadowVersion = 2.0.2 +shadowVersion = 5.2.0 #Testing slf4jVersion = 1.7.13 diff --git a/lib/main/.gitignore b/lib/main/.gitignore deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/lib/test/native/demoendpointlibrary/.gitignore b/lib/test/native/demoendpointlibrary/.gitignore deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/messageapi-core.code-workspace b/messageapi-core.code-workspace new file mode 100644 index 0000000000000000000000000000000000000000..ba87e00a9c596e803095d967dbed04ba42bd818f --- /dev/null +++ b/messageapi-core.code-workspace @@ -0,0 +1,41 @@ +{ + "folders": [ + { + "path": "." + } + ], + "settings": { + "java.configuration.updateBuildConfiguration": "automatic", + "files.associations": { + "gov_noaa_messageapi_endpoints_nativeendpoint.h": "c", + "*.tcc": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "complex": "cpp", + "cstdarg": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "exception": "cpp", + "system_error": "cpp", + "type_traits": "cpp", + "initializer_list": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "new": "cpp", + "ostream": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "cinttypes": "cpp", + "typeinfo": "cpp", + "string": "cpp", + "*.jnilib": "c" + } + } +} \ No newline at end of file diff --git a/resources/docker/Dockerfile.develop b/resources/docker/Dockerfile.develop new file mode 100644 index 0000000000000000000000000000000000000000..2b558117118eafae5ca383be69d91407c557244f --- /dev/null +++ b/resources/docker/Dockerfile.develop @@ -0,0 +1,42 @@ +#Dockerfile for RHEL7 MessageAPI Build on UBI (Openshift Compatible) +#This dockerfile installs the system so that it can be interactively developed and built. +#All build tools are installed and paths are set properly. Some probing tools are also +#installed automatically for development. + +#Base Image (RHEL7 UBI) +FROM registry.access.redhat.com/ubi7/ubi:latest + +#Install standard RHEL7 tools +RUN yum -y install --disableplugin=subscription-manager \ + locate vim unzip wget git java-11-openjdk-devel gcc gcc-gfortran gcc-c++ make \ + && yum --disableplugin=subscription-manager clean all + +#Install Java Variables +RUN cd $(dirname $(readlink -f $(which java))) && cd .. \ + && export JAVA_HOME=$PWD \ + && touch /etc/profile.d/java.sh \ + && echo "export JAVA_HOME=${JAVA_HOME}" > /etc/profile.d/java.sh \ + && echo "export PATH=${JAVA_HOME}/bin:$PATH" >> /etc/profile.d/java.sh \ + && echo "export CLASSPATH=${JAVA_HOME}/bin:${CLASSPATH}" >> /etc/profile.d/java.sh + +#Install Gradle and Variables +RUN wget https://services.gradle.org/distributions/gradle-5.4.1-bin.zip -P /tmp \ + && unzip -d /opt/gradle /tmp/gradle-*.zip \ + && export GRADLE_HOME=/opt/gradle/gradle-5.4.1 \ + && touch /etc/profile.d/gradle.sh \ + && echo "export GRADLE_HOME=${GRADLE_HOME}" > /etc/profile.d/gradle.sh \ + && echo "export PATH=${GRADLE_HOME}/bin:$PATH" >> /etc/profile.d/gradle.sh + +#Add default type user 'messageapi' +RUN useradd messageapi + +#Change to new 'messageapi' user +USER messageapi + +#Set PATH and other user variables in bashrc +RUN cd $(dirname $(readlink -f $(which java))) && cd .. \ + && export JAVA_HOME=$PWD \ + && echo "PATH=${JAVA_HOME}/bin:\$PATH" >> ~/.bashrc \ + && export GRADLE_HOME=/opt/gradle/gradle-5.4.1 \ + && echo "PATH=${GRADLE_HOME}/bin:\$PATH" >> ~/.bashrc \ + && source ~/.bashrc \ No newline at end of file diff --git a/.gitlab-ci.yml b/resources/gitlab/.gitlab-ci.yml similarity index 92% rename from .gitlab-ci.yml rename to resources/gitlab/.gitlab-ci.yml index ff45d18384e7769fa6cddf60bd4901fb520452fa..a5fd31c48e0aa2cacc3644193ef1cb7042c3ed8c 100644 --- a/.gitlab-ci.yml +++ b/resources/gitlab/.gitlab-ci.yml @@ -1,4 +1,4 @@ -#Testing 123456789012345 +#Gitlab Runner Configuration for Automatic CI/CD stages: - test - build diff --git a/resources/test/basic-native/parameters.json b/resources/test/basic-native/parameters.json index 768cf2b60d475bcc6a4a37bca2959c6a02eb1fcd..24746d2ba64a3057ea8b8858c7ed1bababe71913 100644 --- a/resources/test/basic-native/parameters.json +++ b/resources/test/basic-native/parameters.json @@ -27,10 +27,11 @@ "fields": ["initial-value", "string-test", "int-list-test"]}], "connections": [{"id": "1", "collections": ["coll-1"], - "constructor": {"native-library": "/Users/rberkheimer/projects/asos/ingest/libraries/messageapi/lib/test/native/demoendpointlibrary/libDemoEndpointLibrary.jnilib", + "constructor": {"native-library": "/workspaces/messageapi/libs/test/c/endpoint/libEndpointDemo.so", "default-fields": [{"id": "test-integer", "type": "integer", - "required": false}, + "required": false, + "value": 5}, {"id": "return-list", "type": "list(string)", "required": false}], diff --git a/resources/test/containers/simple/clisam/transformations.json b/resources/test/containers/simple/clisam/transformations.json index 1fef7fc6369c0e468a9ddda67f7eb7d4b36ee3db..a16ae7cbe0abdc23d6198967204fc00a4092ac50 100644 --- a/resources/test/containers/simple/clisam/transformations.json +++ b/resources/test/containers/simple/clisam/transformations.json @@ -2,19 +2,28 @@ "transformations": [ { "id": "join-test", - "operator": "join", + "operator": "gov.noaa.messageapi.transformations.joins.StringFieldJoin", "constructor": {"join-field": "key", - "collection-field": "mix-and-match"}, + "collection-field": "mix-and-match", + "fields": [ + "key", + "record", + "filename", + "type", + "mix-and-match" + ]}, "records": {"parent": {"CLASSIFIER": ["namespace", "condition-test"]}, - "child": {"COLLECTION": "mix-and-match"}}, - "fields": ["key", "record", "filename", "type", "mix-and-match"] + "child": {"COLLECTION": "mix-and-match"}} }, { "id": "reduce-test", - "operator": "reduce-sum", + "operator": "gov.noaa.messageapi.transformations.reductions.ReduceTransformation", "constructor": {"reduce-field": "mix-and-match", - "reduce-target": "mix-and-match-reduction"}, - "records": {"reduce-list" : {"TRANSFORMATION": "join-test"}}, - "fields": ["key", "mix-and-match-reduction"] + "reduce-target": "mix-and-match-reduction", + "fields":[ + "key", + "mix-and-match-reduction" + ]}, + "records": {"reduce-list" : {"TRANSFORMATION": "join-test"}} }] } diff --git a/resources/test/containers/simple/condition-test/transformations.json b/resources/test/containers/simple/condition-test/transformations.json index 1295c607426a21bb265988dc1e4e94a5e27960ac..f1972e640e8031e234896c5476cd8806c50e2275 100644 --- a/resources/test/containers/simple/condition-test/transformations.json +++ b/resources/test/containers/simple/condition-test/transformations.json @@ -2,19 +2,28 @@ "transformations": [ { "id": "join-test", - "operator": "join", + "operator": "gov.noaa.messageapi.transformations.joins.StringFieldJoin", "constructor": {"join-field": "key", - "collection-field": "mix-and-match"}, + "collection-field": "mix-and-match", + "fields": [ + "key", + "record", + "filename", + "type", + "mix-and-match" + ]}, "records": {"parent": {"CLASSIFIER": ["namespace", "condition-test"]}, - "child": {"TRANSFORMATION": "reduce-test"}}, - "fields": ["key", "record", "filename", "type", "mix-and-match"] + "child": {"TRANSFORMATION": "reduce-test"}} }, { "id": "reduce-test", - "operator": "reduce", + "operator": "gov.noaa.messageapi.transformations.reductions.ReduceTransformation", "constructor": {"reduce-field": "mix-and-match", - "reduce-target": "mix-and-match-reduction"}, - "records": {"reduce-list" : "UUID"}, - "fields": ["key", "mix-and-match-reduction"] + "reduce-target": "mix-and-match-reduction", + "fields": [ + "key", + "mix-and-match-reduction" + ]}, + "records": {"reduce-list" : "UUID"} }] } diff --git a/resources/test/file-reader-native/manifest.json b/resources/test/file-reader-native/manifest.json new file mode 100644 index 0000000000000000000000000000000000000000..10767e14f61f8a808bd91029649f8e609acec822 --- /dev/null +++ b/resources/test/file-reader-native/manifest.json @@ -0,0 +1,26 @@ +{ + "plugin": "gov.noaa.messageapi.sessions.DefaultSession", + "constructor": { + "schema": { + "plugin": "gov.noaa.messageapi.schemas.DefaultSchema", + "constructor": { + "fields": "/workspaces/messageapi/resources/test/file-reader-native/parameters.json" + } + }, + "container": { + "plugin": "gov.noaa.messageapi.containers.DefaultContainer", + "constructor": { + "collections": "/workspaces/messageapi/resources/test/file-reader-native/parameters.json" + } + }, + "protocol": { + "plugin": "gov.noaa.messageapi.protocols.DefaultProtocol", + "constructor": { + "endpoints": [{ + "plugin": "gov.noaa.messageapi.test.endpoints.InMemoryFileReader", + "connections": "/workspaces/messageapi/resources/test/file-reader-native/parameters.json" + }] + } + } + } +} \ No newline at end of file diff --git a/resources/test/file-reader-native/parameters.json b/resources/test/file-reader-native/parameters.json new file mode 100644 index 0000000000000000000000000000000000000000..d96be1f5d42b800bd276e648746ccdb57495f62a --- /dev/null +++ b/resources/test/file-reader-native/parameters.json @@ -0,0 +1,11 @@ +{ + "fields": [{"id": "file-path", + "type": "string", + "required": true}], + "collections": [{"id": "coll-1", + "fields": ["file-path"]}], + "connections": [{"id": "conn-1", + "collections": ["coll-1"], + "constructor": {"file-fields": "file-path"}, + "fields" : ["value","number", "length"]}] +} \ No newline at end of file diff --git a/resources/test/file-reader/manifest.json b/resources/test/file-reader/manifest.json index 66a710f02645e6baecffd67b024eb024aaacde93..c834247d9fab4f43221809989281f29c1a0644c5 100644 --- a/resources/test/file-reader/manifest.json +++ b/resources/test/file-reader/manifest.json @@ -18,8 +18,7 @@ "metadata": "{}/resources/test/metadata/file-reader/container.json", "collections": "{}/resources/test/file-reader/parameters.json", "transformations": { - "map": "{}/resources/test/file-reader/parameters.json", - "factory": "gov.noaa.messageapi.test.factories.transformations.FileReaderFactory" + "map": "{}/resources/test/file-reader/parameters.json" } } }, diff --git a/resources/test/file-reader/parameters.json b/resources/test/file-reader/parameters.json index f3617f900e3e172627908f5e18863ac5decd445b..3bbac60d5184337306be6423f9f196e651336708 100644 --- a/resources/test/file-reader/parameters.json +++ b/resources/test/file-reader/parameters.json @@ -12,10 +12,10 @@ "fields": ["file-path"], "conditions": ["is-relative-path"]}], "transformations": [{"id": "trans-1", - "operator": "fix-relative-paths", - "constructor": {"transform-key": "file-collection"}, - "records": {"file-collection": {"COLLECTION": "coll-1"}}, - "fields": ["file-path"]}], + "operator": "gov.noaa.messageapi.test.transformations.FixRelativePathsTransformation", + "constructor": {"transform-key": "file-collection", + "fields": ["file-path"]}, + "records": {"file-collection": {"COLLECTION": "coll-1"}}}], "connections": [{"id": "conn-1", "transformations": ["trans-1"], "constructor": {"file-fields": "file-path"}, diff --git a/resources/test/native-transformation/manifest.json b/resources/test/native-transformation/manifest.json new file mode 100644 index 0000000000000000000000000000000000000000..3d86b46889b4e18f5e53bc027227582756bfd423 --- /dev/null +++ b/resources/test/native-transformation/manifest.json @@ -0,0 +1,27 @@ +{ + "plugin": "gov.noaa.messageapi.sessions.DefaultSession", + "constructor": { + "schema": { + "plugin": "gov.noaa.messageapi.schemas.DefaultSchema", + "constructor": { + "fields": "{}/resources/test/native-transformation/parameters.json" + } + }, + "container": { + "plugin": "gov.noaa.messageapi.containers.DefaultContainer", + "constructor": { + "collections": "{}/resources/test/native-transformation/parameters.json", + "transformations": {"map": "{}/resources/test/native-transformation/parameters.json"} + } + }, + "protocol": { + "plugin": "gov.noaa.messageapi.protocols.DefaultProtocol", + "constructor": { + "endpoints": [{ + "plugin": "gov.noaa.messageapi.endpoints.EvaluationEndpoint", + "connections": "{}/resources/test/native-transformation/parameters.json" + }] + } + } + } +} \ No newline at end of file diff --git a/resources/test/native-transformation/parameters.json b/resources/test/native-transformation/parameters.json new file mode 100644 index 0000000000000000000000000000000000000000..0e99a869bc3b945e6d1b2e781a8b3dbeb226ebfc --- /dev/null +++ b/resources/test/native-transformation/parameters.json @@ -0,0 +1,38 @@ +{ + "fields": [ + { + "id": "initial-value", + "type": "integer", + "required": true + }, + { + "id": "string-test", + "type": "string", + "required": false + }, + { + "id": "null-test", + "type": "string", + "required": false + }, + { + "id": "int-list-test", + "type": "list(int)", + "required": true, + "value": [0,1,2,3,4,5,6] + }], + "collections": [{"id": "collection-1", + "fields": ["initial-value", "string-test", "int-list-test", "null-test"]}], + "transformations": [ + { + "id": "transform-1", + "operator": "gov.noaa.messageapi.transformations.NativeTransformation", + "constructor": { + "native-library": "/workspaces/messageapi/libs/test/c/transformation/libTransformationDemo.so" + }, + "records": {"test_key": {"COLLECTION": "collection-1"}}} + ], + "connections": [{"id": "connection-1", + "transformations": ["transform-1"], + "constructor": {}}] +} diff --git a/resources/test/sessions/condition-test.json b/resources/test/sessions/condition-test.json index e5f0289b91d892face723040d9516515da697aea..efb490a039d775fddacd63cd7ca48c6ff5410e4d 100644 --- a/resources/test/sessions/condition-test.json +++ b/resources/test/sessions/condition-test.json @@ -12,10 +12,7 @@ "constructor": { "metadata": "{}/resources/test/containers/simple/condition-test/metadata.json", "collections": "{}/resources/test/containers/simple/condition-test/collections.json", - "transformations": { - "map": "{}/resources/test/containers/simple/condition-test/transformations.json", - "factory": "gov.noaa.messageapi.factories.SimpleTransformationFactory" - } + "transformations": {"map": "{}/resources/test/containers/simple/condition-test/transformations.json"} } }, "protocol": { diff --git a/resources/test/sessions/email-smtp-test.json b/resources/test/sessions/email-smtp-test.json index 9d507d4b0d692e0de620d97b2ca3214c0dea4f38..22b6af6b596593e847ad333735fb466f5e0ac969 100644 --- a/resources/test/sessions/email-smtp-test.json +++ b/resources/test/sessions/email-smtp-test.json @@ -7,8 +7,7 @@ "container": {"plugin": "gov.noaa.messageapi.containers.DefaultContainer", "constructor": {"metadata": "{}/resources/test/containers/simple/email/metadata.json", "collections": "{}/resources/test/containers/simple/email/collections.json", - "transformations": {"map": "{}/resources/test/containers/simple/email/transformations.json", - "factory": "gov.noaa.messageapi.factories.SimpleTransformationFactory"}}}, + "transformations": {"map": "{}/resources/test/containers/simple/email/transformations.json"}}}, "protocol": {"plugin": "gov.noaa.messageapi.protocols.DefaultProtocol", "constructor": {"metadata": "{}/resources/test/protocols/email/simple/metadata.json", "endpoints": [{"plugin": "gov.noaa.messageapi.test.endpoints.EmailEndpointTest", diff --git a/resources/test/sessions/sqlite-jdbc-clisam.json b/resources/test/sessions/sqlite-jdbc-clisam.json index ad7161abeef76c16b90f49c45f8772a002a7677d..5f5122d6298cc1babdd90329cbd011267ba8c880 100644 --- a/resources/test/sessions/sqlite-jdbc-clisam.json +++ b/resources/test/sessions/sqlite-jdbc-clisam.json @@ -7,8 +7,7 @@ "container": {"plugin": "gov.noaa.messageapi.containers.DefaultContainer", "constructor": {"metadata": "{}/resources/test/containers/simple/clisam/metadata.json", "collections": "{}/resources/test/containers/simple/clisam/collections.json", - "transformations": {"map": "{}/resources/test/containers/simple/clisam/transformations.json", - "factory": "gov.noaa.messageapi.factories.SimpleTransformationFactory"}}}, + "transformations": {"map": "{}/resources/test/containers/simple/clisam/transformations.json"}}}, "protocol": {"plugin": "gov.noaa.messageapi.protocols.DefaultProtocol", "constructor": {"metadata": "{}/resources/test/protocols/jdbc/sqlite/clisam/metadata.json", "endpoints": [{"plugin": "gov.noaa.messageapi.test.endpoints.EmailEndpointTest", diff --git a/scripts/build/c/main/Makefile b/scripts/build/c/main/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..96abd3f99157374e45e4eb83ddf6ec0945e1e854 --- /dev/null +++ b/scripts/build/c/main/Makefile @@ -0,0 +1,167 @@ +### This is a Makefile for creating the native session shared library. +# The majority of this Makefile is standard. +# There are a few specific requirements and other notable things to keep in mind when using this Makefile: +# 1. You must have a JDK installed as well as the JRE. This library requires the jni.h header and the shared libraries for jli and jvm. +# 2. JAVA_HOME must be set to your JDK home directory. This Makefile references JAVA_HOME in looking for jni.h, libjli.so, and libjvm.so. + +#Library info +LIBRARY_NAME=messageapi +MAJOR_VERSION=1 +MINOR_VERSION=0 +PATCH_VERSION=0 + +LINKER_NAME=lib$(LIBRARY_NAME).so +SO_NAME=$(LINKER_NAME).$(MAJOR_VERSION) +REAL_NAME=$(LINKER_NAME).$(MAJOR_VERSION).$(MINOR_VERSION).$(PATCH_VERSION) + +#Compute Root Project Path from Makefile path +CURRENT_DIR=$(PWD) +PROJECT_ROOT=$(firstword $(subst /scripts/build/c/main, ,$(CURRENT_DIR))) + +#Set target directories +BUILD_DIR=$(PROJECT_ROOT)/build/c/main +SRC_DIR=$(BUILD_DIR)/src +COMPILE_DIR=$(BUILD_DIR)/compile +HEADER_DIR=$(BUILD_DIR)/headers +LIB_DIR=$(BUILD_DIR)/libs +TEMPLATE_DIR=$(BUILD_DIR)/templates + +ARTIFACT_DIR=$(PROJECT_ROOT)/dist/artifacts/c/$(LIBRARY_NAME)_$(MAJOR_VERSION)_$(MINOR_VERSION)_$(PATCH_VERSION) + +#Source Template Directory +TEMPLATE_SRC_DIR=$(PROJECT_ROOT)/scripts/build/c/templates + +#Include Paths for JNI (dependent on Java Home being set) +JNI_H_DIR=$(JAVA_HOME)/include +JNIMD_H_DIR=$(JAVA_HOME)/include/linux +JVM_SO_DIR=$(JAVA_HOME)/lib/server +JLI_SO_DIR=$(JAVA_HOME)/lib/jli + +export LD_LIBRARY_PATH=$(JLI_SO_DIR):$(JVM_SO_DIR) + +#Compilers +CXX=g++ +CC=gcc + +#Source Code and Header Sets +SCRIPT_SRC_DIR=$(PROJECT_ROOT)/scripts/install/c/main + +C_DIR=$(PROJECT_ROOT)/src/c/main/ + +C_SRC_FILES= + +C_FQ_SRC_FILES=$(addprefix $(C_DIR), $(C_SRC_FILES)) + +C_H_FILES=structs/messageapi_structs.h + +C_FULL_H_FILES=wrappers/endpoint/gov_noaa_messageapi_endpoints_NativeEndpoint.h \ +wrappers/transformation/gov_noaa_messageapi_transformations_NativeTransformation.h + +C_FQ_H_FILES=$(addprefix $(C_DIR), $(C_H_FILES)) + +C_FQ_FULL_H_FILES=$(addprefix $(C_DIR), $(C_FULL_H_FILES)) + +CPP_DIR=$(PROJECT_ROOT)/src/cpp/main/ + +CPP_SRC_FILES=utils/general/jni/JniUtils.cpp utils/general/type/TypeUtils.cpp utils/general/list/ListUtils.cpp \ +utils/general/map/MapUtils.cpp utils/api/condition/ConditionUtils.cpp utils/api/field/FieldUtils.cpp \ +utils/api/records/schema/RecordUtils.cpp utils/api/rejection/RejectionUtils.cpp utils/api/packet/PacketUtils.cpp \ +utils/api/session/SessionUtils.cpp utils/api/request/RequestUtils.cpp utils/api/response/ResponseUtils.cpp \ +api/session/MessageApiSession.cpp libs/session/MessageApiSessionLib.cpp + +CPP_FULL_SRC_FILES=utils/api/endpoint/EndpointUtils.cpp utils/api/records/protocol/ProtocolRecordUtils.cpp \ +utils/api/transformation/TransformationUtils.cpp api/endpoint/MessageApiEndpoint.cpp \ +api/transformation/MessageApiTransformation.cpp libs/endpoint/MessageApiEndpointLib.cpp \ +libs/transformation/MessageApiTransformationLib.cpp + +CPP_FQ_SRC_FILES=$(addprefix $(CPP_DIR), $(CPP_SRC_FILES)) + +CPP_FQ_FULL_SRC_FILES=$(addprefix $(CPP_DIR), $(CPP_FULL_SRC_FILES)) + +CPP_H_FILES=utils/general/jni/JniUtils.h utils/general/type/TypeUtils.h utils/general/list/ListUtils.h \ +utils/general/map/MapUtils.h utils/api/condition/ConditionUtils.h utils/api/field/FieldUtils.h \ +utils/api/records/schema/RecordUtils.h utils/api/rejection/RejectionUtils.h utils/api/packet/PacketUtils.h \ +utils/api/session/SessionUtils.h utils/api/request/RequestUtils.h utils/api/response/ResponseUtils.h \ +api/session/MessageApiSession.h libs/session/MessageApiSessionLib.h + +CPP_FULL_H_FILES=utils/api/endpoint/EndpointUtils.h utils/api/records/protocol/ProtocolRecordUtils.h \ +utils/api/transformation/TransformationUtils.h api/endpoint/MessageApiEndpoint.h \ +api/transformation/MessageApiTransformation.h libs/endpoint/MessageApiEndpointLib.h \ +libs/transformation/MessageApiTransformationLib.h + +CPP_FQ_H_FILES=$(addprefix $(CPP_DIR), $(CPP_H_FILES)) + +CPP_FQ_FULL_H_FILES=$(addprefix $(CPP_DIR), $(CPP_FULL_H_FILES)) + +all: check_sys prep build link dist clean + +.PHONY : check_sys prep build link dist clean + +check_sys: + @echo "Checking OS type" +ifneq ($(shell uname),Linux) + @echo "This makefile is for building shared libraries on linux, OS is $(shell uname). Terminating." + @exit 1 +endif + @echo "System OS is Linux, continuing build." + +prep: + @echo "Preparing system for build." + @rm -rf $(BUILD_DIR) + @rm -rf $(ARTIFACT_DIR) + + @mkdir -p $(BUILD_DIR) + @mkdir -p $(SRC_DIR) + @mkdir -p $(COMPILE_DIR) + @mkdir -p $(HEADER_DIR) + @mkdir -p $(LIB_DIR) + @mkdir -p $(TEMPLATE_DIR) + + @mkdir -p $(ARTIFACT_DIR) + +build: + @echo "Copying source and header resources for build." + @cp $(C_FQ_H_FILES) $(HEADER_DIR) + @cp $(CPP_FQ_H_FILES) $(HEADER_DIR) + @echo "Copying installation script to build dir." + @-cd $(SCRIPT_SRC_DIR) && cp install.sh $(BUILD_DIR) + @echo "Finished copying resources." + @echo "Building $(LIBRARY_NAME) in $(PROJECT_ROOT)." + @echo "Compiling object files with position independent code." + @-cd $(COMPILE_DIR) && $(CXX) -c -Wall -fPIC -I$(JNI_H_DIR) -I$(JNIMD_H_DIR) \ + -I$(HEADER_DIR) $(CPP_FQ_SRC_FILES) + @echo "" + @echo "Creating shared library from object files." + @echo "" + @cp $(JVM_SO_DIR)/libjvm.so $(COMPILE_DIR) + @cp $(JLI_SO_DIR)/libjli.so $(COMPILE_DIR) + @-cd $(COMPILE_DIR) && $(CXX) -shared -fPIC -std=c99 \ + -L$(COMPILE_DIR) -Wl,-rpath,$(COMPILE_DIR) \ + -Wl,-soname,$(SO_NAME) -ljli -ljvm -o $(REAL_NAME) *.o + @echo "Build success for the C/C++ session shared library." + +link: + @echo "Linking shared library." + @-cd $(COMPILE_DIR) && ln -s $(REAL_NAME) $(SO_NAME) + @-cd $(COMPILE_DIR) && ln -s $(SO_NAME) $(LINKER_NAME) + @cp $(COMPILE_DIR)/libmessageapi.so $(LIB_DIR) + @cp $(COMPILE_DIR)/libmessageapi.so.* $(LIB_DIR) + @echo "Finished linking shared library." + +dist: + @echo "Copying all headers and source files for full library distribution." + @cp $(C_FQ_FULL_H_FILES) $(HEADER_DIR) + @cp $(CPP_FQ_FULL_H_FILES) $(HEADER_DIR) + @cp $(CPP_FQ_SRC_FILES) $(SRC_DIR) + @cp $(CPP_FQ_FULL_SRC_FILES) $(SRC_DIR) + @cp $(TEMPLATE_SRC_DIR)/Makefile.* $(TEMPLATE_DIR) + @echo "Building tarfile for distribution." + @-cd $(BUILD_DIR) && tar -cf $(LIBRARY_NAME).tar src libs headers templates install.sh + @echo "Moving tarfile to $(ARTIFACT_DIR)." + @-cd $(BUILD_DIR) && mv $(LIBRARY_NAME).tar $(ARTIFACT_DIR) + @echo "Finished build, artifacts are now tarred and available in $(ARTIFACT_DIR)." + +clean: + @echo "Cleaning up build data." + @rm -rf $(BUILD_DIR) + @echo "" diff --git a/scripts/build/c/templates/Makefile.endpoint b/scripts/build/c/templates/Makefile.endpoint new file mode 100644 index 0000000000000000000000000000000000000000..d3940f3aaae8edd7e563f5d6640155d979fe2647 --- /dev/null +++ b/scripts/build/c/templates/Makefile.endpoint @@ -0,0 +1,107 @@ +### This Makefile can be used as a template for writing MessageAPI compatible C/C++ Endpoints that extend the +# NativeEndpoint. +# Note that the goal of native endpoint production is to create a shared library, +# as shared libraries are used by the Java code. Once produced, the fully-qualified shared library should just be referenced in the +# config map for the endpoint itself. If you are reading this, you most likely understand what is necessary, but if not, see the example +# 'native endpoint' in the MessageAPI source code 'test' namespace with associated parameter map. + +# The majority of this Makefile is standard, with only six user specified variables. These are denoted by the comment USER SPECIFIED. +# All user specified variables are at the top of this makefile. The build process is standardized to automatically include MessageAPI resources, +# So if there is an issue at first, make sure you have installed the library correctly (need $MESSAGEAPI_SRC and $MESSAGEAPI_HEADERS env vars). + +# There are a few other system-specific requirements and other notable things to keep in mind when using this Makefile: +## 1. You must have a JDK installed (not JRE). This library requires the jni.h and jnimd.h headers included in your jdk. +## 2. JAVA_HOME must be set to your JDK home directory (one level above the java binary). This Makefile references JAVA_HOME in looking for jni.h and jnimd.h + + +#USER SPECIFIED - Specify where the library will build to. The library itself will be placed in $BUILD_DIR/compile +BUILD_DIR= +#USER SPECIFIED - Specify the base name of the lib (e.g., if lib to be built as libMyEndpoint.so, put MyEndpoint here) +LIBRARY_NAME= + +#USER SPECIFIED - Specify The next two lines with Fully Qualified paths to your C source (if any) and headers (if any) in dependency order. +#he last C file should correspond to the Messageapi endpoint wrapper (the header is in the $MESSAGEAPI_HEADERS dir and is auto-included). +#This C file is the entry point for the library. See $MESSAGEAPI_HEADERS/gov_noaa_messageapi_endpoints_NativeEndpoint.h for the signature of +#the class that must be wrapped. +USER_C_SRC_FILES= +USER_C_H_FILES= + +#USER SPECIFIED - Specify The next two lines with Fully Qualified paths to your C++ source (if any) and headers (if any) in dependency order. +USER_CPP_SRC_FILES= +USER_CPP_H_FILES= + +############### The next sections are usually default. You can also contact the MessageAPI maintainers for help if there are issues. ################### +COMPILE_DIR=$(BUILD_DIR)/compile#.o and .so files produced here +HEADER_DIR=$(BUILD_DIR)/headers#.h files copied here before build (for central include path) + +SO_NAME=lib$(LIBRARY_NAME).so + +#The following represent directories for JNI Libraries that must be included during C and CPP compilation. +#The following represent a standard RHEL 7/8 system with OpenJDK. +JNIDIR=$(JAVA_HOME)/include +JNIMDDIR=$(JAVA_HOME)/include/linux + +#compilers +CXX=g++ +CC=gcc + + +MAPI_C_H_FILES=/messageapi_structs.h /gov_noaa_messageapi_endpoints_NativeEndpoint.h +MAPI_C_FQ_H_FILES=$(addprefix $(MESSAGEAPI_HEADERS), $(MAPI_C_H_FILES)) + +MAPI_CPP_SRC_FILES=/JniUtils.cpp /TypeUtils.cpp /MapUtils.cpp \ +/ListUtils.cpp /ConditionUtils.cpp /FieldUtils.cpp \ +/EndpointUtils.cpp /ProtocolRecordUtils.cpp /RecordUtils.cpp \ +/RejectionUtils.cpp /PacketUtils.cpp \ +/MessageApiEndpoint.cpp /MessageApiEndpointLib.cpp + +MAPI_CPP_FQ_SRC_FILES=$(addprefix $(MESSAGEAPI_SRC), $(MAPI_CPP_SRC_FILES)) + +MAPI_CPP_H_FILES=/JniUtils.h /TypeUtils.h /MapUtils.h \ +/ListUtils.h /ConditionUtils.h /FieldUtils.h \ +/EndpointUtils.h /ProtocolRecordUtils.h /RecordUtils.h \ +/RejectionUtils.h /PacketUtils.h \ +/MessageApiEndpoint.h /MessageApiEndpointLib.h + +MAPI_CPP_FQ_H_FILES=$(addprefix $(MESSAGEAPI_SRC), $(MAPI_CPP_H_FILES)) + + +all: check_sys prep build + +.PHONY : check_sys prep build + +check_sys: + @echo "Checking OS type" +ifneq ($(shell uname),Linux) + @echo "This makefile is for building shared libraries on linux, OS is $(shell uname). Terminating." + @exit 1 +endif + @echo "System OS is Linux, continuing build." + +prep: + @echo "Preparing system for build." + @rm -rf $(BUILD_DIR) + @mkdir -p $(BUILD_DIR) + @mkdir -p $(COMPILE_DIR) + @mkdir -p $(HEADER_DIR) + +build: + @echo "Building $(LIBRARY_NAME) as $(SO_NAME) in $(COMPILE_DIR)" + @echo "Copying all headers to include path." + @cp $(MAPI_C_FQ_H_FILES) $(HEADER_DIR) + @cp $(MAPI_CPP_FQ_H_FILES) $(HEADER_DIR) + @cp $(USER_C_H_FILES) $(HEADER_DIR) + @cp $(USER_CPP_H_FILES) $(HEADER_DIR) + + @echo "Compiling C++ object files with position independent code." + @echo "" + @-cd $(COMPILE_DIR) && $(CXX) -I$(HEADER_DIR) -I$(JNIDIR) -I$(JNIMDDIR) -fPIC -c $(MAPI_CPP_FQ_SRC_FILES) $(USER_CPP_SRC_FILES) + @echo "" + @echo "Compiling C object files with position independent code." + @echo "" + @-cd $(COMPILE_DIR) && $(CC) -I$(HEADER_DIR) -I$(JNIDIR) -I$(JNIMDDIR) -fPIC -std=c99 -c $(MAPI_C_FQ_SRC_FILES) $(USER_C_SRC_FILES) + @echo "" + @echo "Creating shared library." + @echo "" + @-cd $(COMPILE_DIR) && $(CXX) -shared -fPIC -std=c99 *.o -o $(SO_NAME) + @echo "Build success for $(LIBRARY_NAME) as $(COMPILE_DIR)/$(SO_NAME)" \ No newline at end of file diff --git a/scripts/build/c/templates/Makefile.session b/scripts/build/c/templates/Makefile.session new file mode 100644 index 0000000000000000000000000000000000000000..7b218c4d9bad584222a23b2772fbc075135237ff --- /dev/null +++ b/scripts/build/c/templates/Makefile.session @@ -0,0 +1,82 @@ +### This Makefile can be used as a template for writing programs that use that use the MessageAPI session shared library. +# Note that the goal of this makefile is to provide a template that can produce C/C++ programs (not shared libraries). It will +# provide access to the MessageAPI shared library during build. +# Note that this library does not package the messageapi .so or .so dependencies of the MessageAPI lib (libjli and libjvm). +# When DEPLOYING a program that uses the MessageAPI library to a new system, either the LD_LIBRARY_PATH environment variable should be set/exported with the +# locations of libjli.so, libjvm.so, and libmessageapi.so, or they should be installed to the standard location for libs (if root). +# For the purposes of this build (on the build system), if MessageAPI was installed, +# the LD_LIBRARY_PATH should already be set in the users .bashrc. If there is an issue +# with linking, please contact the MessageAPI maintainers for assistance. + +# The majority of this Makefile is standard, with only 4 user specified variables. These are denoted by the comment USER SPECIFIED. +# All user specified variables are at the top of this makefile. The build process is standardized to automatically include MessageAPI resources, +# So if there is an issue at first, make sure you have installed the library correctly (need $MESSAGEAPI_LIBS and $MESSAGEAPI_HEADERS env vars). + +# There are a few other system-specific requirements and other notable things to keep in mind when using this Makefile: +## 1. You must have a JDK installed (not JRE). Building something with messageapi also requires the jni.h and jnimd.h headers included in your jdk. +## 2. JAVA_HOME must be set to your JDK home directory (one level above the java binary). This Makefile references JAVA_HOME in looking for jni.h and jnimd.h + + +#USER SPECIFIED: Enter the name of your program binary (e.g., MySession.bin) +PROGRAM_NAME= + + +#USER SPECIFIED: Enter the name of the build dir. The project will be built in +BUILD_DIR= + +#USER SPECIFIED: Enter the fully qualified paths of your source files and header files here: +SRC_FILES= +H_FILES= + + +########################## Everything below here is fairly standardized. Usually no need to adjust below unless there is an issue.############ +COMPILE_DIR=$(BUILD_DIR)/compile#.o files and program binary produced here +HEADER_DIR=$(BUILD_DIR)/headers#.h files copied here before build (for central include path) +DEPS_DIR=$(BUILD_DIR)/deps#copy the messageapi lib here before build. + +#The following represent directories for JNI Libraries that must be included during C and CPP compilation. +#The following represent a standard RHEL 7/8 system with OpenJDK. +JNIDIR=$(JAVA_HOME)/include +JNIMDDIR=$(JAVA_HOME)/include/linux + +#compilers +CC=gcc + +all: check_sys prep copy-shared build + +.PHONY : check_sys prep copy-shared build clean + +check_sys: + @echo "Checking OS type" +ifneq ($(shell uname),Linux) + @echo "This makefile is for building shared libraries on linux, OS is $(shell uname). Terminating." + @exit 1 +endif + @echo "System OS is Linux, continuing build." + +prep: + @echo "Preparing system for build." + @rm -rf $(BUILD_DIR) + @mkdir -p $(BUILD_DIR) + @mkdir -p $(COMPILE_DIR) + @mkdir -p $(HEADER_DIR) + @mkdir -p $(DEPS_DIR) + @echo "Finished preparing system for build." + +copy-shared: + @echo "Extracting and copying production artifacts as shared resources for build." + @cp $(MESSAGEAPI_LIBS)/* $(DEPS_DIR) + @cp $(H_FILES) $(HEADER_DIR) + @echo "Finished copying resources." + + +build: + @echo "Building $(PROGRAM_NAME) in $(COMPILE_DIR)" + @echo "Compiling C and/or C++ object files with position independent code." + @-cd $(COMPILE_DIR) && $(CC) -fPIC -std=c99 -I$(MESSAGEAPI_HEADERS) -I$(HEADER_DIR) -I$(JNIDIR) -I$(JNIMDDIR) -L$(DEPS_DIR) -Wl,-rpath,$(DEPS_DIR) -lmessageapi $(SRC_FILES) -o $(PROGRAM_NAME) + @echo "Completed build of $(COMPILE_DIR)/$(PROGRAM_NAME)." + +clean: + @echo "Cleaning up build refuse." + @rm -rf $(BUILD_DIR) + @echo "Finished cleaning up build refuse." \ No newline at end of file diff --git a/scripts/build/c/templates/Makefile.transformation b/scripts/build/c/templates/Makefile.transformation new file mode 100644 index 0000000000000000000000000000000000000000..8aea53c3b61bc35145627d820323d07b3aef9afc --- /dev/null +++ b/scripts/build/c/templates/Makefile.transformation @@ -0,0 +1,106 @@ +### This Makefile can be used as a template for writing MessageAPI compatible C/C++ transformations that extend the +# NativeTransformation. +# Note that the goal of native transformation production is to create a shared library, +# as shared libraries are used by the Java code. Once produced, the fully-qualified shared library should just be referenced in the +# config map for the transformation itself. If you are reading this, you most likely understand what is necessary, but if not, see the example +# 'native transformation' in the MessageAPI source code 'test' namespace with associated parameter map. + +# The majority of this Makefile is standard, with only six user specified variables. These are denoted by the comment USER SPECIFIED. +# All user specified variables are at the top of this makefile. The build process is standardized to automatically include MessageAPI resources, +# So if there is an issue at first, make sure you have installed the library correctly (need $MESSAGEAPI_SRC and $MESSAGEAPI_HEADERS env vars). + +# There are a few other system-specific requirements and other notable things to keep in mind when using this Makefile: +## 1. You must have a JDK installed (not JRE). This library requires the jni.h and jnimd.h headers included in your jdk. +## 2. JAVA_HOME must be set to your JDK home directory (one level above the java binary). This Makefile references JAVA_HOME in looking for jni.h and jnimd.h + +#USER SPECIFIED - Specify where the library will build to. The library itself will be placed in $BUILD_DIR/compile +BUILD_DIR= +#USER SPECIFIED - Specify the base name of the lib (e.g., if lib to be built as libMyTransformation.so, put MyTransformation here) +LIBRARY_NAME= + +#USER SPECIFIED - Specify The next two lines with Fully Qualified paths to your C source (if any) and headers (if any) in dependency order. +#he last C file should correspond to the Messageapi endpoint wrapper (the header is in the $MESSAGEAPI_HEADERS dir and is auto-included). +#This C file is the entry point for the library. See $MESSAGEAPI_HEADERS/gov_noaa_messageapi_transformations_NativeTransformation.h for the signature of +#the class that must be wrapped. +USER_C_SRC_FILES= +USER_C_H_FILES= + +#USER SPECIFIED - Specify The next two lines with Fully Qualified paths to your C++ source (if any) and headers (if any) in dependency order. +USER_CPP_SRC_FILES= +USER_CPP_H_FILES= + +############### The next sections are usually default. You can also contact the MessageAPI maintainers for help if there are issues. ################### +COMPILE_DIR=$(BUILD_DIR)/compile#.o and .so files produced here +HEADER_DIR=$(BUILD_DIR)/headers#.h files copied here before build (for central include path) + +SO_NAME=lib$(LIBRARY_NAME).so + +#The following represent directories for JNI Libraries that must be included during C and CPP compilation. +#The following represent a standard RHEL 7/8 system with OpenJDK. +JNIDIR=$(JAVA_HOME)/include +JNIMDDIR=$(JAVA_HOME)/include/linux + +#compilers +CXX=g++ +CC=gcc + + +MAPI_C_H_FILES=/messageapi_structs.h /gov_noaa_messageapi_transformations_NativeTransformation.h +MAPI_C_FQ_H_FILES=$(addprefix $(MESSAGEAPI_HEADERS), $(MAPI_C_H_FILES)) + +MAPI_CPP_SRC_FILES=/JniUtils.cpp /TypeUtils.cpp /MapUtils.cpp \ +/ListUtils.cpp /ConditionUtils.cpp /FieldUtils.cpp \ +/TransformationUtils.cpp /RecordUtils.cpp \ +/RejectionUtils.cpp /PacketUtils.cpp \ +/MessageApiTransformation.cpp /MessageApiTransformationLib.cpp + +MAPI_CPP_FQ_SRC_FILES=$(addprefix $(MESSAGEAPI_SRC), $(MAPI_CPP_SRC_FILES)) + +MAPI_CPP_H_FILES=/JniUtils.h /TypeUtils.h /MapUtils.h \ +/ListUtils.h /ConditionUtils.h /FieldUtils.h \ +/TransformationUtils.h /RecordUtils.h \ +/RejectionUtils.h /PacketUtils.h \ +/MessageApiTransformation.h /MessageApiTransformationLib.h + +MAPI_CPP_FQ_H_FILES=$(addprefix $(MESSAGEAPI_SRC), $(MAPI_CPP_H_FILES)) + + +all: check_sys prep build + +.PHONY : check_sys prep build + +check_sys: + @echo "Checking OS type" +ifneq ($(shell uname),Linux) + @echo "This makefile is for building shared libraries on linux, OS is $(shell uname). Terminating." + @exit 1 +endif + @echo "System OS is Linux, continuing build." + +prep: + @echo "Preparing system for build." + @rm -rf $(BUILD_DIR) + @mkdir -p $(BUILD_DIR) + @mkdir -p $(COMPILE_DIR) + @mkdir -p $(HEADER_DIR) + +build: + @echo "Building $(LIBRARY_NAME) as $(SO_NAME) in $(COMPILE_DIR)" + @echo "Copying all headers to include path." + @cp $(MAPI_C_FQ_H_FILES) $(HEADER_DIR) + @cp $(MAPI_CPP_FQ_H_FILES) $(HEADER_DIR) + @cp $(USER_C_H_FILES) $(HEADER_DIR) + @cp $(USER_CPP_H_FILES) $(HEADER_DIR) + + @echo "Compiling C++ object files with position independent code." + @echo "" + @-cd $(COMPILE_DIR) && $(CXX) -I$(HEADER_DIR) -I$(JNIDIR) -I$(JNIMDDIR) -fPIC -c $(MAPI_CPP_FQ_SRC_FILES) $(USER_CPP_SRC_FILES) + @echo "" + @echo "Compiling C object files with position independent code." + @echo "" + @-cd $(COMPILE_DIR) && $(CC) -I$(HEADER_DIR) -I$(JNIDIR) -I$(JNIMDDIR) -fPIC -std=c99 -c $(MAPI_C_FQ_SRC_FILES) $(USER_C_SRC_FILES) + @echo "" + @echo "Creating shared library." + @echo "" + @-cd $(COMPILE_DIR) && $(CXX) -shared -fPIC -std=c99 *.o -o $(SO_NAME) + @echo "Build success for $(LIBRARY_NAME) as $(COMPILE_DIR)/$(SO_NAME)" \ No newline at end of file diff --git a/scripts/build/c/test/endpoint/Makefile b/scripts/build/c/test/endpoint/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..0ad4e1e2b5a9fc53080c6734dd426792b300a2ce --- /dev/null +++ b/scripts/build/c/test/endpoint/Makefile @@ -0,0 +1,105 @@ +### This Makefile can be used as a template for writing MessageAPI compatible C/C++ Endpoints that extend the +# NativeEndpoint. This Makefile itself is setup for the test endpoint, but with a few modifications, it can be +# updated for user endpoint content. Note that the goal of native endpoint production is to create a shared library, +# as shared libraries are used by the Java code. Once produced, the shared library should just be referenced in the +# config map for the endpoint itself (fully qualified of course). + +# The majority of this Makefile is standard, with very few user specified things. + +# There are a few specific requirements and other notable things to keep in mind when using this Makefile: +## 1. You must have a JDK installed (not JRE). This library requires the jni.h and jnimd.h headers included in your jdk. +## 2. JAVA_HOME must be set to your JDK home directory. This Makefile references JAVA_HOME in looking for jni.h and jnimd.h + +#The following is used to bootstrap the PROJECT_ROOT +CURRENT_DIR=$(PWD) + +#The following represents the root project path. In this tailored example, we use a relative path to the project root. +#In your own Makefile, this variable can be set directly. +PROJECT_ROOT=$(firstword $(subst /scripts/build/c/test, ,$(CURRENT_DIR))) + +#Set target directories - this is where the library will build from/to. +BUILD_DIR=$(PROJECT_ROOT)/build/c/test/endpoint +COMPILE_DIR=$(BUILD_DIR)/compile#.o files produced here +HEADER_DIR=$(BUILD_DIR)/headers#.h files copied here before build (for central include path) +LIB_DIR=$(PROJECT_ROOT)/libs/test/c/endpoint#.so moved here before test + + +#The following var represents the base name of the shared .so library that will be created and referenced in the job map. +LIBRARY_NAME=EndpointDemo +SO_NAME=lib$(LIBRARY_NAME).so + +#The following represent directories for JNI Libraries that must be included during C and CPP compilation. +#The following represent a standard RHEL 7/8 system with OpenJDK. +JNIDIR=$(JAVA_HOME)/include +JNIMDDIR=$(JAVA_HOME)/include/linux + +#compilers +CXX=g++ +CC=gcc + +C_DIR=$(PROJECT_ROOT)/src/c/ + +C_SRC_FILES=test/endpoints/endpoint_lib/EndpointWrapper.c +C_FQ_SRC_FILES=$(addprefix $(C_DIR), $(C_SRC_FILES)) + +C_H_FILES=main/structs/messageapi_structs.h main/wrappers/endpoint/gov_noaa_messageapi_endpoints_NativeEndpoint.h +C_FQ_H_FILES=$(addprefix $(C_DIR), $(C_H_FILES)) + +CPP_DIR=$(PROJECT_ROOT)/src/cpp/main/ + +CPP_SRC_FILES=utils/general/jni/JniUtils.cpp utils/general/type/TypeUtils.cpp utils/general/map/MapUtils.cpp \ +utils/general/list/ListUtils.cpp utils/api/condition/ConditionUtils.cpp utils/api/field/FieldUtils.cpp \ +utils/api/endpoint/EndpointUtils.cpp utils/api/records/protocol/ProtocolRecordUtils.cpp utils/api/records/schema/RecordUtils.cpp \ +utils/api/rejection/RejectionUtils.cpp utils/api/packet/PacketUtils.cpp \ +api/endpoint/MessageApiEndpoint.cpp libs/endpoint/MessageApiEndpointLib.cpp + +CPP_FQ_SRC_FILES=$(addprefix $(CPP_DIR), $(CPP_SRC_FILES)) + +CPP_H_FILES=utils/general/jni/JniUtils.h utils/general/type/TypeUtils.h utils/general/map/MapUtils.h \ +utils/general/list/ListUtils.h utils/api/condition/ConditionUtils.h utils/api/field/FieldUtils.h \ +utils/api/endpoint/EndpointUtils.h utils/api/records/protocol/ProtocolRecordUtils.h utils/api/records/schema/RecordUtils.h \ +utils/api/rejection/RejectionUtils.h utils/api/packet/PacketUtils.h \ +api/endpoint/MessageApiEndpoint.h libs/endpoint/MessageApiEndpointLib.h + +CPP_FQ_H_FILES=$(addprefix $(CPP_DIR), $(CPP_H_FILES)) + + +all: check_sys prep build + +.PHONY : check_sys prep build + +check_sys: + @echo "Checking OS type" +ifneq ($(shell uname),Linux) + @echo "This makefile is for building shared libraries on linux, OS is $(shell uname). Terminating." + @exit 1 +endif + @echo "System OS is Linux, continuing build." + +prep: + @echo "Preparing system for build." + @rm -rf $(BUILD_DIR) + @mkdir -p $(BUILD_DIR) + @mkdir -p $(COMPILE_DIR) + @mkdir -p $(HEADER_DIR) + @mkdir -p $(LIB_DIR) + +build: + @echo "Building $(LIBRARY_NAME) as $(SO_NAME) in $(LIB_DIR)" + @echo "Copying all headers to include path." + @cp $(C_FQ_H_FILES) $(HEADER_DIR) + @cp $(CPP_FQ_H_FILES) $(HEADER_DIR) + + @echo "Compiling C++ object files with position independent code." + @echo "" + @-cd $(COMPILE_DIR) && $(CXX) -I$(HEADER_DIR) -I$(JNIDIR) -I$(JNIMDDIR) -fPIC -c $(CPP_FQ_SRC_FILES) + @echo "" + @echo "Compiling C object files with position independent code." + @echo "" + @-cd $(COMPILE_DIR) && $(CC) -I$(HEADER_DIR) -I$(JNIDIR) -I$(JNIMDDIR) -fPIC -std=c99 -c $(C_FQ_SRC_FILES) + @echo "" + @echo "Creating shared library." + @echo "" + @-cd $(COMPILE_DIR) && $(CXX) -shared -fPIC -std=c99 *.o -o $(SO_NAME) + @-cd $(COMPILE_DIR) && mv $(SO_NAME) $(LIB_DIR) + @echo "Build success for $(LIBRARY_NAME) as $(LIB_DIR)/$(SO_NAME)" \ No newline at end of file diff --git a/scripts/build/c/test/session/Makefile b/scripts/build/c/test/session/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..1eeb3e6e4d5c49f400fe77993bd15a55b8acd0ef --- /dev/null +++ b/scripts/build/c/test/session/Makefile @@ -0,0 +1,99 @@ +### This Makefile can be used as a template for writing MessageAPI compatible C/C++ Transformations that extend the +# NativeTransformation. This Makefile itself is setup for the test endpoint, but with a few modifications, it can be +# updated for user endpoint content. Note that the goal of native endpoint production is to create a shared library, +# as shared libraries are used by the Java code. Once produced, the shared library should just be referenced in the +# config map for the endpoint itself (fully qualified of course). + +# The majority of this Makefile is standard, with very few user specified things. + +# There are a few specific requirements and other notable things to keep in mind when using this Makefile: +## 1. You must have a JDK installed (not JRE). This library requires the jni.h and jnimd.h headers included in your jdk. +## 2. JAVA_HOME must be set to your JDK home directory. This Makefile references JAVA_HOME in looking for jni.h and jnimd.h + +#Messageapi C/C++ Artifact Versioning +SO_NAME=messageapi +MAJOR_VERSION=1 +MINOR_VERSION=0 +PATCH_VERSION=0 + +#The following is used to bootstrap the PROJECT_ROOT +CURRENT_DIR=$(PWD) + +#The following represents the root project path. In this tailored example, we use a relative path to the project root. +#In your own Makefile, this variable can be set directly. +PROJECT_ROOT=$(firstword $(subst /scripts/build/c/test, ,$(CURRENT_DIR))) + +#Set target directories - this is where the library will build from/to. +ARTIFACT_DIR=$(PROJECT_ROOT)/dist/artifacts/c +BUILD_DIR=$(PROJECT_ROOT)/build/c/test/session +SO_DIR=$(BUILD_DIR)/resources +COMPILE_DIR=$(BUILD_DIR)/compile#.o files produced here +HEADER_DIR=$(BUILD_DIR)/headers#.h files copied here before build (for central include path) +BIN_DIR=$(PROJECT_ROOT)/libs/test/c/session#.so moved here before test +DEPS_DIR=$(BIN_DIR)/so + + +#The following var represents the +BIN_NAME=SessionDemo.bin + +#The following represent directories for JNI Libraries that must be included during C and CPP compilation. +#The following represent a standard RHEL 7/8 system with OpenJDK. +JNIDIR=$(JAVA_HOME)/include +JNIMDDIR=$(JAVA_HOME)/include/linux +JVM_SO_DIR=$(JAVA_HOME)/lib/server +JLI_SO_DIR=$(JAVA_HOME)/lib/jli + +export LD_LIBRARY_PATH=$(JLI_SO_DIR):$(JVM_SO_DIR) + +#compilers +CC=gcc + +C_DIR=$(PROJECT_ROOT)/src/c/ + +C_SRC_FILES=test/sessions/session_demo/SessionDemo.c +C_FQ_SRC_FILES=$(addprefix $(C_DIR), $(C_SRC_FILES)) + + +all: check_sys prep copy-shared build clean + +.PHONY : check_sys prep copy-shared build clean + +check_sys: + @echo "Checking OS type" +ifneq ($(shell uname),Linux) + @echo "This makefile is for building shared libraries on linux, OS is $(shell uname). Terminating." + @exit 1 +endif + @echo "System OS is Linux, continuing build." + +prep: + @echo "Preparing system for build." + @rm -rf $(BUILD_DIR) + @mkdir -p $(BUILD_DIR) + @mkdir -p $(SO_DIR) + @mkdir -p $(COMPILE_DIR) + @mkdir -p $(HEADER_DIR) + @mkdir -p $(BIN_DIR) + @mkdir -p $(DEPS_DIR) + @echo "Finished preparing system for build." + +copy-shared: + @echo "Extracting and copying production artifacts as shared resources for build." + @cp $(ARTIFACT_DIR)/$(SO_NAME)_$(MAJOR_VERSION)_$(MINOR_VERSION)_$(PATCH_VERSION)/$(SO_NAME).tar $(SO_DIR) + @-cd $(SO_DIR) && tar -xf $(SO_NAME).tar + @cp $(SO_DIR)/libs/* $(DEPS_DIR) + @cp $(SO_DIR)/headers/* $(HEADER_DIR) + @echo "Finished copying resources." + + +build: + @echo "Building $(BIN_NAME) in $(BIN_DIR)" + @echo "Compiling C object files with position independent code." + @-cd $(COMPILE_DIR) && $(CC) -fPIC -std=c99 -I$(HEADER_DIR) -I$(JNIDIR) -I$(JNIMDDIR) -L$(DEPS_DIR) -Wl,-rpath,$(DEPS_DIR) -l$(SO_NAME) $(C_FQ_SRC_FILES) -o $(BIN_NAME) + @cp $(COMPILE_DIR)/$(BIN_NAME) $(BIN_DIR) + @echo "Completed build of $(BIN_DIR)/$(BIN_NAME)." + +clean: + @echo "Cleaning up build refuse." + @rm -rf $(BUILD_DIR) + @echo "Finished cleaning up build refuse." \ No newline at end of file diff --git a/scripts/build/c/test/transformation/Makefile b/scripts/build/c/test/transformation/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..44b26f6e8a76d8bab4bd778e31e0ae328c5c422f --- /dev/null +++ b/scripts/build/c/test/transformation/Makefile @@ -0,0 +1,105 @@ +### This Makefile can be used as a template for writing MessageAPI compatible C/C++ Transformations that extend the +# NativeTransformation. This Makefile itself is setup for the test transformation, but with a few modifications, it can be +# updated for user transformation content. Note that the goal of native transformation production is to create a shared library, +# as shared libraries are used by the Java code. Once produced, the shared library should just be referenced in the +# config map for the transformation itself (fully qualified of course). + +# The majority of this Makefile is standard, with very few user specified things. + +# There are a few specific requirements and other notable things to keep in mind when using this Makefile: +## 1. You must have a JDK installed (not JRE). This library requires the jni.h and jnimd.h headers included in your jdk. +## 2. JAVA_HOME must be set to your JDK home directory. This Makefile references JAVA_HOME in looking for jni.h and jnimd.h + +#The following is used to bootstrap the PROJECT_ROOT +CURRENT_DIR=$(PWD) + +#The following represents the root project path. In this tailored example, we use a relative path to the project root. +#In your own Makefile, this variable can be set directly. +PROJECT_ROOT=$(firstword $(subst /scripts/build/c/test, ,$(CURRENT_DIR))) + +#Set target directories - this is where the library will build from/to. +BUILD_DIR=$(PROJECT_ROOT)/build/c/test/transformation +COMPILE_DIR=$(BUILD_DIR)/compile#.o files produced here +HEADER_DIR=$(BUILD_DIR)/headers#.h files copied here before build (for central include path) +LIB_DIR=$(PROJECT_ROOT)/libs/test/c/transformation#.so moved here before test + + +#The following var represents the base name of the shared .so library that will be created and referenced in the job map. +LIBRARY_NAME=TransformationDemo +SO_NAME=lib$(LIBRARY_NAME).so + +#The following represent directories for JNI Libraries that must be included during C and CPP compilation. +#The following represent a standard RHEL 7/8 system with OpenJDK. +JNIDIR=$(JAVA_HOME)/include +JNIMDDIR=$(JAVA_HOME)/include/linux + +#compilers +CXX=g++ +CC=gcc + +C_DIR=$(PROJECT_ROOT)/src/c/ + +C_SRC_FILES=test/transformations/transformation_lib/TransformationWrapper.c +C_FQ_SRC_FILES=$(addprefix $(C_DIR), $(C_SRC_FILES)) + +C_H_FILES=main/structs/messageapi_structs.h main/wrappers/transformation/gov_noaa_messageapi_transformations_NativeTransformation.h +C_FQ_H_FILES=$(addprefix $(C_DIR), $(C_H_FILES)) + +CPP_DIR=$(PROJECT_ROOT)/src/cpp/main/ + +CPP_SRC_FILES=utils/general/jni/JniUtils.cpp utils/general/type/TypeUtils.cpp utils/general/map/MapUtils.cpp \ +utils/general/list/ListUtils.cpp utils/api/condition/ConditionUtils.cpp utils/api/field/FieldUtils.cpp \ +utils/api/transformation/TransformationUtils.cpp utils/api/records/schema/RecordUtils.cpp \ +utils/api/rejection/RejectionUtils.cpp utils/api/packet/PacketUtils.cpp \ +api/transformation/MessageApiTransformation.cpp libs/transformation/MessageApiTransformationLib.cpp + +CPP_FQ_SRC_FILES=$(addprefix $(CPP_DIR), $(CPP_SRC_FILES)) + +CPP_H_FILES=utils/general/jni/JniUtils.h utils/general/type/TypeUtils.h utils/general/map/MapUtils.h \ +utils/general/list/ListUtils.h utils/api/condition/ConditionUtils.h utils/api/field/FieldUtils.h \ +utils/api/transformation/TransformationUtils.h utils/api/records/schema/RecordUtils.h \ +utils/api/rejection/RejectionUtils.h utils/api/packet/PacketUtils.h \ +api/transformation/MessageApiTransformation.h libs/transformation/MessageApiTransformationLib.h + +CPP_FQ_H_FILES=$(addprefix $(CPP_DIR), $(CPP_H_FILES)) + + +all: check_sys prep build + +.PHONY : check_sys prep build + +check_sys: + @echo "Checking OS type" +ifneq ($(shell uname),Linux) + @echo "This makefile is for building shared libraries on linux, OS is $(shell uname). Terminating." + @exit 1 +endif + @echo "System OS is Linux, continuing build." + +prep: + @echo "Preparing system for build." + @rm -rf $(BUILD_DIR) + @mkdir -p $(BUILD_DIR) + @mkdir -p $(COMPILE_DIR) + @mkdir -p $(HEADER_DIR) + @mkdir -p $(LIB_DIR) + +build: + @echo "Building $(LIBRARY_NAME) as $(SO_NAME) in $(LIB_DIR)" + @echo "Copying all headers to include path." + @cp $(C_FQ_H_FILES) $(HEADER_DIR) + @cp $(CPP_FQ_H_FILES) $(HEADER_DIR) + + @echo "Compiling C++ object files with position independent code." + @echo "" + @-cd $(COMPILE_DIR) && $(CXX) -I$(HEADER_DIR) -I$(JNIDIR) -I$(JNIMDDIR) -fPIC -c $(CPP_FQ_SRC_FILES) + @echo "" + @echo "Compiling C object files with position independent code." + @echo "" + @-cd $(COMPILE_DIR) && $(CC) -I$(HEADER_DIR) -I$(JNIDIR) -I$(JNIMDDIR) -fPIC -std=c99 -c $(C_FQ_SRC_FILES) + @echo "" + @echo "Creating shared library." + @echo "" + @-cd $(COMPILE_DIR) && $(CXX) -shared -fPIC -std=c99 *.o -o $(SO_NAME) + @-cd $(COMPILE_DIR) && mv $(SO_NAME) $(LIB_DIR) + @echo "Build success for $(LIBRARY_NAME) as $(LIB_DIR)/$(SO_NAME)" \ No newline at end of file diff --git a/scripts/install/c/main/install.sh b/scripts/install/c/main/install.sh new file mode 100755 index 0000000000000000000000000000000000000000..e5ee3925cdb6cd0aeea0abd8b3776781d93d9dcb --- /dev/null +++ b/scripts/install/c/main/install.sh @@ -0,0 +1,157 @@ +#!/bin/bash + +#Updates the LD_LIBRARY_PATH for libjli and libjvm. Exits install if no java on path. +update_ld_library_paths () { + echo "" + if java -version 2>&1 >/dev/null | grep -E "\S+\s+version"; then + echo "The java binary was found on the path; using to determine path of libjli.so and libjvm.so" + local java_bin + local java_home + local java_lib + local java_jli + local java_jvm + java_bin=$(dirname "$(readlink -f "$(which java)")") + java_home=$(cd "${java_bin}" && cd .. && echo "${PWD}") + java_lib=$(cd "${java_home}" && cd lib && echo "${PWD}") + java_jli=$(cd "${java_lib}" && cd jli && echo "${PWD}") + java_jvm=$(cd "${java_lib}" && cd server && echo "${PWD}") + if [[ -n $java_jli && -n $java_jvm ]]; then + echo "Updating LD_LIBRARY_PATH with locations for libjli and libjvm in bashrc." + sed '/#messageapi_jvm_ld_library_path/d' "${BASHRC}" > "${BASHRC_TMP}" + mv "${BASHRC_TMP}" "${BASHRC}" + echo "export LD_LIBRARY_PATH=${java_jli}:${java_jvm}:\$LD_LIBRARY_PATH #messageapi_jvm_ld_library_path" >> "${BASHRC}" + echo "Successfully updated LD_LIBRARY_PATH in ${BASHRC}" + else + echo "Could not find the libjli or libjvm folders. C/C++ lib will not work correctly." + echo "Please contact messageapi maintainers for help, it appears you have a non-supported java setup." + echo "Quitting installation." + exit 1 + fi + else + echo "java binary not found on path, C/C++ lib will not work correctly." + echo "Please update your PATH to include the location of the java binary, or contact messageapi maintainers for help." + echo "Quitting installation." + exit 1 + fi + echo "" +} + +update_headers_var () { + echo "" + echo "Updating the MESSAGEAPI_HEADERS environment variable in $(whoami)'s ~/.bashrc." + sed '/#messageapi_c_cpp_set_headers/d' "${BASHRC}" > "${BASHRC_TMP}" + mv "${BASHRC_TMP}" "${BASHRC}" + echo "export MESSAGEAPI_HEADERS=${HEADERS_INSTALL_DIR} #messageapi_c_cpp_set_headers" >> "${BASHRC}" + echo "Added a 'MESSAGEAPI_HEADERS' environment variable to ${BASHRC} for convenient inclusion of library headers." + echo "When creating a C/C++ session, endpoint, condition, or transformation, you can use the MESSAGEAPI_HEADERS as the include location." + echo "Build file templates for each of these is provided in the templates directory, accessible via the MESSAGEAPI_TEMPLATES environment variable." + echo "" +} + +update_libs_var () { + echo "" + echo "Updating the MESSAGEAPI_LIBS environment variable in $(whoami)'s ~/.bashrc." + sed '/#messageapi_c_cpp_set_libs/d' "${BASHRC}" > "${BASHRC_TMP}" + mv "${BASHRC_TMP}" "${BASHRC}" + echo "export MESSAGEAPI_LIBS=${LIBS_INSTALL_DIR} #messageapi_c_cpp_set_libs" >> "${BASHRC}" + sed '/#messageapi_c_cpp_ld_library_path/d' "${BASHRC}" > "${BASHRC_TMP}" + mv "${BASHRC_TMP}" "${BASHRC}" + echo "export LD_LIBRARY_PATH=${LIBS_INSTALL_DIR}:\$LD_LIBRARY_PATH #messageapi_c_cpp_ld_library_path" >> "${BASHRC}" + echo "Added a 'MESSAGEAPI_LIBS' environment variable to ${BASHRC} for convenient inclusion of the C/C++ shared library." + echo "Updated the LD_LIBRARY_PATH environment variable to include the MESSAGEAPI_LIBS path." + echo "When creating a C/C++ program that uses the MessageAPI session library, you can use the MESSAGEAPI_LIBS as the linking location." + echo "" +} + +update_src_var () { + echo "" + echo "Updating the MESSAGEAPI_SRC environment variable in $(whoami)'s ~/.bashrc." + sed '/#messageapi_c_cpp_set_src/d' "${BASHRC}" > "${BASHRC_TMP}" + mv "${BASHRC_TMP}" "${BASHRC}" + echo "export MESSAGEAPI_SRC=${SRC_INSTALL_DIR} #messageapi_c_cpp_set_src" >> "${BASHRC}" + echo "Added a 'MESSAGEAPI_SRC' environment variable to ${BASHRC} for convenient inclusion of the C/C++ source files." + echo "When creating a C/C++ session, endpoint, condition, or transformation, you can use the MESSAGEAPI_SRC for base source paths during build." + echo "Build file templates for each of these is provided in the templates directory, accessible via the MESSAGEAPI_TEMPLATES environment variable." + echo "" +} + +update_template_var () { + echo "" + echo "Updating the MESSAGEAPI_TEMPLATES environment variable in $(whoami)'s ~/.bashrc." + sed '/#messageapi_c_cpp_build_templates/d' "${BASHRC}" > "${BASHRC_TMP}" + mv "${BASHRC_TMP}" "${BASHRC}" + echo "export MESSAGEAPI_TEMPLATES=${TEMPLATE_INSTALL_DIR} #messageapi_c_cpp_build_templates" >> "${BASHRC}" + echo "Added a 'MESSAGEAPI_TEMPLATES' environment variable to ${BASHRC} for convenient access to the C/C++ build templates." + echo "These templates are set up to use the installation paths for messageapi source code, libraries, and headers." + echo "To use them, copy the template to your desired build location, fill out the fields with USER FIELD comments, and run 'make'." + echo "" +} + +install_headers () { + echo "" + echo "Installing messageapi C/C++ headers to ${HEADERS_INSTALL_DIR}." + rm -rf "${HEADERS_INSTALL_DIR}" + mkdir -p "${HEADERS_INSTALL_DIR}" + cp headers/* "${HEADERS_INSTALL_DIR}" + echo "Finished installing messageapi C/C++ headers to ${HEADERS_INSTALL_DIR}." + echo "" +} + +install_libs () { + echo "" + echo "Installing messageapi C/C++ shared libs to ${LIBS_INSTALL_DIR}." + rm -rf "${LIBS_INSTALL_DIR}" + mkdir -p "${LIBS_INSTALL_DIR}" + cp libs/* "${LIBS_INSTALL_DIR}" + echo "Finished installing messageapi C/C++ shared libs to ${LIBS_INSTALL_DIR}." + echo "" +} + +install_src () { + echo "" + echo "Installing messageapi C/C++ src files to ${SRC_INSTALL_DIR}." + rm -rf "${SRC_INSTALL_DIR}" + mkdir -p "${SRC_INSTALL_DIR}" + cp src/* "${SRC_INSTALL_DIR}" + echo "Finished installing messageapi C/C++ src files to ${SRC_INSTALL_DIR}." + echo "" +} + +install_templates () { + echo "" + echo "Installing messageapi C/C++ build templates to ${TEMPLATE_INSTALL_DIR}." + rm -rf "${TEMPLATE_INSTALL_DIR}" + mkdir -p "${TEMPLATE_INSTALL_DIR}" + cp templates/* "${TEMPLATE_INSTALL_DIR}" + echo "Finished installing messageapi C/C++ build templates to ${TEMPLATE_INSTALL_DIR}." + echo "" +} + +refresh_shell () { + unset LD_LIBRARY_PATH +} + +BASHRC=${HOME}/.bashrc +BASHRC_TMP=${HOME}/.bashrc_tmp + +INSTALL_DIR=${HOME}/.messageapi/c +LIBS_INSTALL_DIR=${INSTALL_DIR}/libs +HEADERS_INSTALL_DIR=${INSTALL_DIR}/headers +SRC_INSTALL_DIR=${INSTALL_DIR}/src +TEMPLATE_INSTALL_DIR=${INSTALL_DIR}/templates + +#Main Body +echo "" +echo "Installing the MessageAPI C/C++ libs, headers, src, and build templates for the current user $(whoami)" +update_ld_library_paths +install_libs +update_libs_var +install_headers +update_headers_var +install_src +update_src_var +install_templates +update_template_var +refresh_shell +echo "Finished installing the MessageAPI C/C++ libs, headers, src, and build templates for user $(whoami)." +echo "" \ No newline at end of file diff --git a/scripts/install/java/main/install.sh b/scripts/install/java/main/install.sh new file mode 100755 index 0000000000000000000000000000000000000000..d357a7f91718c22c210e5bd23529337955a3ad79 --- /dev/null +++ b/scripts/install/java/main/install.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +update_classpath_var () { + echo "" + echo "Updating the CLASSPATH environment variable in $(whoami)'s ~/.bashrc." + sed '/#messageapi_core_set_classpath/d' "${BASHRC}" > "${BASHRC_TMP}" + mv "${BASHRC_TMP}" "${BASHRC}" + echo "export CLASSPATH=${CORE_INSTALL_DIR}/${JAR_NAME}:\$CLASSPATH #messageapi_core_set_classpath" >> "${BASHRC}" + echo "" +} + +install_core_jar () { + echo "" + echo "Installing messageapi core jar to ${CORE_INSTALL_DIR}." + rm -rf "${CORE_INSTALL_DIR}" + mkdir -p "${CORE_INSTALL_DIR}" + cp "${JAR_NAME}" "${CORE_INSTALL_DIR}" + echo "Finished installing messageapi core jar to ${CORE_INSTALL_DIR}." + echo "" +} + +refresh_shell () { + unset CLASSPATH +} + + +BASHRC=${HOME}/.bashrc +BASHRC_TMP=${HOME}/.bashrc_tmp + +CORE_INSTALL_DIR=${HOME}/.messageapi/java/jars + +MAJOR_VERSION=1 +MINOR_VERSION=0 +PATCH_VERSION=0 +JAR_NAME=messageapi-core-${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}.jar + +#Main Body +echo "" +echo "Installing the MessageAPI-Core Jar for the current user $(whoami)" +install_core_jar +update_classpath_var +refresh_shell +echo "Finished installing the MessageAPI-Core Jar for user $(whoami)." +echo "" \ No newline at end of file diff --git a/scripts/install/package/install.sh b/scripts/install/package/install.sh new file mode 100755 index 0000000000000000000000000000000000000000..93af4178ebd43291f1423afd79bb52510e065b2f --- /dev/null +++ b/scripts/install/package/install.sh @@ -0,0 +1,79 @@ +#!/bin/bash + +set -o errexit + +die () { + echo >&2 "$@" + exit 1 +} + +install_core () { + echo "Installing MessageAPI Core version ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}" + #Set target specific vars + local lib_path=dist/artifacts/java/messageapi_${MAJOR_VERSION}_${MINOR_VERSION}_${PATCH_VERSION} + local file_path=${BASE_URL}/${BRANCH}/${lib_path}/${FILE_NAME}${FILE_SUFFIX} + #Set tmp dir location + local tmp_dir=${HOME}/.messageapi/tmp + #Retrieve file + rm -rf "${tmp_dir}" + mkdir -p "${tmp_dir}/java" + cd "${tmp_dir}/java" + wget "${file_path}" --no-check-certificate + mv "${FILE_NAME}${FILE_SUFFIX}" "${FILE_NAME}" + tar -xf "${FILE_NAME}" + ./install.sh + rm -rf "${tmp_dir}" + echo "Finished installing MessageAPI Core version ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}" +} + +install_c_cpp () { + echo "Installing MessageAPI for C/C++ version ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}" + #Set target specific vars + local lib_path=dist/artifacts/c/messageapi_${MAJOR_VERSION}_${MINOR_VERSION}_${PATCH_VERSION} + local file_path=${BASE_URL}/${BRANCH}/${lib_path}/${FILE_NAME}${FILE_SUFFIX} + #Set tmp dir location + local tmp_dir=${HOME}/.messageapi/tmp + #Retrieve file + rm -rf "${tmp_dir}" + mkdir -p "${tmp_dir}/c" + cd "${tmp_dir}/c" + wget "${file_path}" --no-check-certificate + mv "${FILE_NAME}${FILE_SUFFIX}" "${FILE_NAME}" + tar -xf "${FILE_NAME}" + ./install.sh + rm -rf "${tmp_dir}" + echo "Finished installing MessageAPI for C/C++ version ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}" +} + +#Main Body + +echo "This is the main install script to install various MessageAPI packages as precompiled artifacts (not source) built for use on RHEL7." +echo "To use, pass in an argument - current options are CORE or C_CPP" +echo "If choosing an option with dependencies, those dependencies will first be installed automatically (e.g., C_CPP depends on CORE)." +echo "To change the version of download, open this file and update the BRANCH, MAJOR_VERSION, MINOR_VERSION, or PATCH_VERSION vars as desired." +echo "The version that is configured to be automatically downloaded is the most recently approved release." + +[ "$#" -eq 1 ] || die "target argument required (CORE or C_CPP), $# provided" + +BASE_URL=https://git.ncei.noaa.gov/sesb/sscs/messageapi/-/raw +BRANCH=master +FILE_NAME=messageapi.tar +FILE_SUFFIX="?inline=false" +MAJOR_VERSION=1 +MINOR_VERSION=0 +PATCH_VERSION=0 + +TARGET=$1 + +case ${TARGET} in + CORE) + install_core + ;; + C_CPP) + install_core + install_c_cpp + ;; + *) + echo "Not a valid option." + ;; +esac \ No newline at end of file diff --git a/scripts/install/package/install_k3.sh b/scripts/install/package/install_k3.sh new file mode 100755 index 0000000000000000000000000000000000000000..f0191c6eaaaa0ccf0a2bcd157bcdd00c6bbd640d --- /dev/null +++ b/scripts/install/package/install_k3.sh @@ -0,0 +1,79 @@ +#!/bin/bash + +set -o errexit + +die () { + echo >&2 "$@" + exit 1 +} + +install_core () { + echo "Installing MessageAPI Core version ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}" + #Set target specific vars + local lib_path=dist/artifacts/java/messageapi_${MAJOR_VERSION}_${MINOR_VERSION}_${PATCH_VERSION} + local file_path=${BASE_URL}/${BRANCH}/${lib_path}/${FILE_NAME}${FILE_SUFFIX} + #Set tmp dir location + local tmp_dir=${HOME}/.messageapi/tmp + #Retrieve file + rm -rf "${tmp_dir}" + mkdir -p "${tmp_dir}/java" + cd "${tmp_dir}/java" + wget "${file_path}" --no-check-certificate + mv "${FILE_NAME}${FILE_SUFFIX}" "${FILE_NAME}" + tar -xf "${FILE_NAME}" + ./install.sh + rm -rf "${tmp_dir}" + echo "Finished installing MessageAPI Core version ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}" +} + +install_c_cpp () { + echo "Installing MessageAPI for C/C++ version ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}" + #Set target specific vars + local lib_path=dist/artifacts/c/messageapi_${MAJOR_VERSION}_${MINOR_VERSION}_${PATCH_VERSION} + local file_path=${BASE_URL}/${BRANCH}/${lib_path}/${FILE_NAME}${FILE_SUFFIX} + #Set tmp dir location + local tmp_dir=${HOME}/.messageapi/tmp + #Retrieve file + rm -rf "${tmp_dir}" + mkdir -p "${tmp_dir}/c" + cd "${tmp_dir}/c" + wget "${file_path}" --no-check-certificate + mv "${FILE_NAME}${FILE_SUFFIX}" "${FILE_NAME}" + tar -xf "${FILE_NAME}" + ./install.sh + rm -rf "${tmp_dir}" + echo "Finished installing MessageAPI for C/C++ version ${MAJOR_VERSION}_${MINOR_VERSION}_${PATCH_VERSION}." +} + +#Main Body + +echo "This is the main install script to install various MessageAPI packages as precompiled artifacts (not source) built for use on RHEL7." +echo "To use, pass in an argument - current options are CORE or C_CPP" +echo "If choosing an option with dependencies, those dependencies will first be installed automatically (e.g., C_CPP depends on CORE)." +echo "To change the version of download, open this file and update the BRANCH, MAJOR_VERSION, MINOR_VERSION, or PATCH_VERSION vars as desired." +echo "The version that is configured to be automatically downloaded is the most recently approved release." + +[ "$#" -eq 1 ] || die "target argument required (CORE or C_CPP), $# provided" + +BASE_URL=https://k3.cicsnc.org/rberkheimer/messageapi/-/raw +BRANCH=mac-develop +FILE_NAME=messageapi.tar +FILE_SUFFIX="?inline=false" +MAJOR_VERSION=1 +MINOR_VERSION=0 +PATCH_VERSION=0 + +TARGET=$1 + +case ${TARGET} in + CORE) + install_core + ;; + C_CPP) + install_core + install_c_cpp + ;; + *) + echo "Not a valid option." + ;; +esac \ No newline at end of file diff --git a/scripts/main/.gitignore b/scripts/main/.gitignore deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/scripts/test/jni/demoendpointlibrary/Makefile b/scripts/test/jni/demoendpointlibrary/Makefile deleted file mode 100644 index a3bada2d43699c4f10fbdafea6a44159f3e84582..0000000000000000000000000000000000000000 --- a/scripts/test/jni/demoendpointlibrary/Makefile +++ /dev/null @@ -1,152 +0,0 @@ -### This is a Makefile for MessageAPI Native Endpoints. -# The majority of this Makefile is standard, with very few user specified things. -# There are a few specific requirements and other notable things to keep in mind when using this Makefile: -## 1. You must have a JDK installed (not JRE). This library requires the jni.h header included in your jdk. -## 2. JAVA_HOME must be set to your JDK home directory. This Makefile references JAVA_HOME in looking for jni.h -## 3. This Makefile assumes a specific project layout when setting the PROJECTPATH. If the Makefile is not working, -## you should look at how it uses PROJECTPATH, ENDPOINT_NAME, and ENDPOINT_TYPE to find required files. -## if your project is set up differently, i.e. custom project layout, then path dependent vars will need to be -## looked at and possibly changed. - -#The following represents the root project path. DO NOT EDIT -SCRIPTDIR=$(PWD) -PROJECTPATH=$(firstword $(subst /scripts/$(ENDPOINT_TYPE)/, ,$(SCRIPTDIR))) - -#The following is used to determine how native resources are compiled. DO NOT EDIT. -UNAME := $(shell uname) - -###################################################### USER SPECIFIED SECTION - PLEASE EDIT ########################### -#USER SPECIFIED -#The following vars are used to route source code and scripts (from the scripts and src dirs) -#to the library dir as compiled files (the job name should match the name of the directory/job map.) -#the job type is simply a test job or a main job and should either be test or main. -ENDPOINT_NAME=demoendpointlibrary -ENDPOINT_TYPE=test - -#USER SPECIFIED -#The following var represents the output name of the JniLib that will be created and referenced in the job map. -#Do not specify the extension (.so/.dll/.jnilib) - these are determined automatically on build. -#The full path to the created library must be referenced in the endpoint config. -LIBNAME=DemoEndpointLibrary - -#USER SPECIFIED -#The following vars should contain strings representing the C, Fortran, and CPP libraries that glue the fortran code to java code. -#These strings should contain the user libraries in the order they need to be compiled (ex, "First.c Second.c Third.c") -#These vars do not need to specify libraries they depend on that are found in the common variables (those are automatically compiled first). -USERC=EndpointWrapper.c -USERCPP= -USERFORTRAN= - -###################################################### END USER SPECIFIED SECTION ########################### - -#The following represent directories for JNI Libraries that must be included during C and CPP compilation. -#These are platform dependent. If you have a default setup, these probably will not have to be modified. -#However, if you have nonstandard include paths, or you are getting errors, this may need to be altered. -ifeq ($(UNAME), Linux) -#The following represent a standard RHEL 7 system. -JNIDIR="$(JAVA_HOME)/include" -JNIMDDIR="$(JAVA_HOME)/include/linux" -JVMHEADERS="$(JAVA_HOME)/include/linux" -endif -ifeq ($(UNAME), Darwin) -#The following represent a standard OSX system. -JNIDIR="$(JAVA_HOME)/include" -JNIMDDIR="$(JAVA_HOME)/include/darwin" -JVMHEADERS="$(JAVA_HOME)/include" -endif - -#compilers -CXX=g++ -CC=gcc -FF=gfortran - -#The following vars contain strings representing common libraries used by all code -#at a project level. These should generally not be touched by users. -COMMONC= -COMMONCPP=JniUtils.cpp TypeUtils.cpp ListUtils.cpp ConditionUtils.cpp FieldUtils.cpp \ -EndpointUtils.cpp ProtocolRecordUtils.cpp RecordUtils.cpp RejectionUtils.cpp PacketUtils.cpp \ -MessageApiEndpoint.cpp MessageApiEndpointLib.cpp -COMMONFORTRAN= -JAVACLASSES:=$(PROJECTPATH)/src/java/main/gov/noaa/messageapi/endpoints/NativeEndpoint.java -JAVAPATH=$(PROJECTPATH)/src/java/main:$(PROJECTPATH)/src/java/main/gov/noaa/messageapi/endpoints - - -#The following contains source code paths derived from the ENDPOINT_NAME and ENDPOINT_TYPE supplied by the user. -COMMONCPATH=$(PROJECTPATH)/src/c/main/common/structs/ -USERCPATH=$(PROJECTPATH)/src/c/$(ENDPOINT_TYPE)/endpoints/$(ENDPOINT_NAME)/ -COMMONCPPPATH=$(PROJECTPATH)/src/cpp/main/common/ -USERCPPPATH=$(PROJECTPATH)/src/cpp/$(ENDPOINT_TYPE)/$(ENDPOINT_NAME)/ -COMMONFORTRANPATH=$(PROJECTPATH)/src/fortran/main/common/ -USERFORTRANPATH=$(PROJECTPATH)/src/fortran/$(ENDPOINT_TYPE)/$(ENDPOINT_NAME)/ - -#The following var contains the target path for the project code. -TARGETPATH="$(PROJECTPATH)/lib/$(ENDPOINT_TYPE)/native/$(ENDPOINT_NAME)/" - -#The following is the target library for the native jni library. -ifeq ($(UNAME), Linux) -#The following represents a standard RHEL 7 system. -LNFLAGS=-dynamiclib -shared -lgfortran -I$(JVMHEADERS) -endif -ifeq ($(UNAME), Darwin) -#The following represents a standard OSX system. -LNFLAGS=-dynamiclib -shared -lgfortran -I$(JVMHEADERS) -framework JavaVM -endif - -CFLAGS=-I$(JVMHEADERS) -I$(COMMONCPPPATH) -I$(COMMONCPATH) -I$(USERCPPPATH) -I$(USERCPATH) -I$(JNIDIR) -I$(JNIMDDIR) -fpic -std=c99 -FFLAGS=-I$(COMMONFORTRANPATH) -I$(USERFORTRANPATH) -fPIC -fopenmp - -#The following is the target library for the native jni library. -ifeq ($(UNAME), Linux) -#The following represents a standard RHEL 7 system. -DYLIB=lib$(LIBNAME).so -endif -ifeq ($(UNAME), Darwin) -#The following represents a standard OSX system. -DYLIB=lib$(LIBNAME).jnilib -endif - -#COMMONFORTRAN1=$(addprefix $(COMMONFORTRANPATH), $(COMMONFORTRAN)) -#USERFORTRAN1=$(addprefix $(USERFORTRANPATH), $(USERFORTRAN)) -COMMONC1=$(addprefix $(COMMONCPATH), $(COMMONC)) -USERC1=$(addprefix $(USERCPATH), $(USERC)) -COMMONCPP1=$(addprefix $(COMMONCPPPATH), $(COMMONCPP)) -USERCPP1=$(addprefix $(USERCPPPATH), $(USERCPP)) - -all: clean gen-headers build - -.PHONY : clean gen-headers build - -gen-headers: - echo "Generating headers. " - echo "" - $(foreach header,$(JAVACLASSES),javac -h $(USERCPATH) -classpath $(JAVAPATH) $(header);) - echo "" - -build: - echo "Building " $(ENDPOINT_NAME) " in " $(PROJECTPATH) - #echo "Compiling Fortran" - #echo "" - #cd $(TARGETPATH) && $(FF) $(FFLAGS) -c $(COMMONFORTRAN1) $(USERFORTRAN1) - #echo "" - echo "Compiling CPP" - echo "" - cd $(TARGETPATH) && $(CXX) $(CFLAGS) -c $(COMMONCPP1) $(USERCPP1) - echo "" - echo "Compiling C" - echo "" - cd $(TARGETPATH) && $(CC) $(CFLAGS) -c $(COMMONC1) $(USERC1) - echo "" - echo "Creating JNI Library" - echo "" - cd $(TARGETPATH) && $(CXX) $(LNFLAGS) *.o -o $(DYLIB) - echo "Build success for " $(ENDPOINT_NAME) - -clean: - echo "Cleaning up." - echo "" - -cd $(TARGETPATH) && rm *.h - -cd $(TARGETPATH) && rm *.o - -cd $(TARGETPATH) && rm *.mod - -cd $(TARGETPATH) && rm *.jnilib - -cd $(TARGETPATH) && rm *.so - echo "" diff --git a/scripts/test/jni/demosession/Makefile b/scripts/test/jni/demosession/Makefile deleted file mode 100644 index d26ed812c1d065bcc9aa52c309fc2a5b1578a7bd..0000000000000000000000000000000000000000 --- a/scripts/test/jni/demosession/Makefile +++ /dev/null @@ -1,150 +0,0 @@ -### This is a Makefile for MessageAPI Native Endpoints. -# The majority of this Makefile is standard, with very few user specified things. -# There are a few specific requirements and other notable things to keep in mind when using this Makefile: -## 1. You must have a JDK installed (not JRE). This library requires the jni.h header included in your jdk. -## 2. JAVA_HOME must be set to your JDK home directory. This Makefile references JAVA_HOME in looking for jni.h -## 3. This Makefile assumes a specific project layout when setting the PROJECTPATH. If the Makefile is not working, -## you should look at how it uses PROJECTPATH, ENDPOINT_NAME, and ENDPOINT_TYPE to find required files. -## if your project is set up differently, i.e. custom project layout, then path dependent vars will need to be -## looked at and possibly changed. - -#The following represents the root project path. DO NOT EDIT -SCRIPTDIR=$(PWD) -PROJECTPATH=$(firstword $(subst /scripts/$(ENDPOINT_TYPE)/, ,$(SCRIPTDIR))) - -#The following is used to determine how native resources are compiled. DO NOT EDIT. -UNAME := $(shell uname) - -###################################################### USER SPECIFIED SECTION - PLEASE EDIT ########################### -#USER SPECIFIED -#The following vars are used to route source code and scripts (from the scripts and src dirs) -#to the library dir as compiled files (the job name should match the name of the directory/job map.) -#the job type is simply a test job or a main job and should either be test or main. -ENDPOINT_NAME=demosession -ENDPOINT_TYPE=test - -#USER SPECIFIED -#The following var represents the output name of the JniLib that will be created and referenced in the job map. -#Do not specify the extension (.so/.dll/.jnilib) - these are determined automatically on build. -#The full path to the created library must be referenced in the endpoint config. -LIBNAME=DemoSession - -#USER SPECIFIED -#The following vars should contain strings representing the C, Fortran, and CPP libraries that glue the fortran code to java code. -#These strings should contain the user libraries in the order they need to be compiled (ex, "First.c Second.c Third.c") -#These vars do not need to specify libraries they depend on that are found in the common variables (those are automatically compiled first). -USERC=EndpointWrapper.c -USERCPP= -USERFORTRAN= - -###################################################### END USER SPECIFIED SECTION ########################### - -#The following represent directories for JNI Libraries that must be included during C and CPP compilation. -#These are platform dependent. If you have a default setup, these probably will not have to be modified. -#However, if you have nonstandard include paths, or you are getting errors, this may need to be altered. -ifeq ($(UNAME), Linux) -#The following represent a standard RHEL 7 system. -JNIDIR="$(JAVA_HOME)/include" -JNIMDDIR="$(JAVA_HOME)/include/linux" -JVMHEADERS="$(JAVA_HOME)/include/linux" -endif -ifeq ($(UNAME), Darwin) -#The following represent a standard OSX system. -JNIDIR="$(JAVA_HOME)/include" -JNIMDDIR="$(JAVA_HOME)/include/darwin" -JVMHEADERS="$(JAVA_HOME)/include" -endif - -#compilers -CXX=g++ -CC=gcc -FF=gfortran - -#The following vars contain strings representing common libraries used by all code -#at a project level. These should generally not be touched by users. -COMMONC= -COMMONCPP=MessageApiEndpoint.cpp MessageApiEndpointLib.cpp -COMMONFORTRAN= -JAVACLASSES:=$(PROJECTPATH)/src/java/main/gov/noaa/messageapi/endpoints/NativeEndpoint.java -JAVAPATH=$(PROJECTPATH)/src/java/main:$(PROJECTPATH)/src/java/main/gov/noaa/messageapi/endpoints - - -#The following contains source code paths derived from the ENDPOINT_NAME and ENDPOINT_TYPE supplied by the user. -COMMONCPATH=$(PROJECTPATH)/src/c/main/common/structs/ -USERCPATH=$(PROJECTPATH)/src/c/$(ENDPOINT_TYPE)/endpoints/$(ENDPOINT_NAME)/ -COMMONCPPPATH=$(PROJECTPATH)/src/cpp/main/common/endpoint/ -USERCPPPATH=$(PROJECTPATH)/src/cpp/$(ENDPOINT_TYPE)/$(ENDPOINT_NAME)/ -COMMONFORTRANPATH=$(PROJECTPATH)/src/fortran/main/common/ -USERFORTRANPATH=$(PROJECTPATH)/src/fortran/$(ENDPOINT_TYPE)/$(ENDPOINT_NAME)/ - -#The following var contains the target path for the project code. -TARGETPATH="$(PROJECTPATH)/lib/$(ENDPOINT_TYPE)/native/$(ENDPOINT_NAME)/" - -#The following is the target library for the native jni library. -ifeq ($(UNAME), Linux) -#The following represents a standard RHEL 7 system. -LNFLAGS=-dynamiclib -shared -lgfortran -I$(JVMHEADERS) -endif -ifeq ($(UNAME), Darwin) -#The following represents a standard OSX system. -LNFLAGS=-dynamiclib -shared -lgfortran -I$(JVMHEADERS) -framework JavaVM -endif - -CFLAGS=-I$(JVMHEADERS) -I$(COMMONCPPPATH) -I$(COMMONCPATH) -I$(USERCPPPATH) -I$(USERCPATH) -I$(JNIDIR) -I$(JNIMDDIR) -fpic -std=c99 -FFLAGS=-I$(COMMONFORTRANPATH) -I$(USERFORTRANPATH) -fPIC -fopenmp - -#The following is the target library for the native jni library. -ifeq ($(UNAME), Linux) -#The following represents a standard RHEL 7 system. -DYLIB=lib$(LIBNAME).so -endif -ifeq ($(UNAME), Darwin) -#The following represents a standard OSX system. -DYLIB=lib$(LIBNAME).jnilib -endif - -#COMMONFORTRAN1=$(addprefix $(COMMONFORTRANPATH), $(COMMONFORTRAN)) -#USERFORTRAN1=$(addprefix $(USERFORTRANPATH), $(USERFORTRAN)) -COMMONC1=$(addprefix $(COMMONCPATH), $(COMMONC)) -USERC1=$(addprefix $(USERCPATH), $(USERC)) -COMMONCPP1=$(addprefix $(COMMONCPPPATH), $(COMMONCPP)) -USERCPP1=$(addprefix $(USERCPPPATH), $(USERCPP)) - -all: clean gen-headers build - -.PHONY : clean gen-headers build - -gen-headers: - echo "Generating headers. " - echo "" - $(foreach header,$(JAVACLASSES),javac -h $(USERCPATH) -classpath $(JAVAPATH) $(header);) - echo "" - -build: - echo "Building " $(ENDPOINT_NAME) " in " $(PROJECTPATH) - #echo "Compiling Fortran" - #echo "" - #cd $(TARGETPATH) && $(FF) $(FFLAGS) -c $(COMMONFORTRAN1) $(USERFORTRAN1) - #echo "" - echo "Compiling CPP" - echo "" - cd $(TARGETPATH) && $(CXX) $(CFLAGS) -c $(COMMONCPP1) $(USERCPP1) - echo "" - echo "Compiling C" - echo "" - cd $(TARGETPATH) && $(CC) $(CFLAGS) -c $(COMMONC1) $(USERC1) - echo "" - echo "Creating JNI Library" - echo "" - cd $(TARGETPATH) && $(CXX) $(LNFLAGS) *.o -o $(DYLIB) - echo "Build success for " $(ENDPOINT_NAME) - -clean: - echo "Cleaning up." - echo "" - -cd $(TARGETPATH) && rm *.h - -cd $(TARGETPATH) && rm *.o - -cd $(TARGETPATH) && rm *.mod - -cd $(TARGETPATH) && rm *.jnilib - -cd $(TARGETPATH) && rm *.so - echo "" diff --git a/src/c/main/common/structs/messageapi_structs.h b/src/c/main/common/structs/messageapi_structs.h deleted file mode 100644 index 27f2bdc8144027d4df41c601d68d90f7baca3c5b..0000000000000000000000000000000000000000 --- a/src/c/main/common/structs/messageapi_structs.h +++ /dev/null @@ -1,98 +0,0 @@ - -#ifndef _Included_messageapi_structs -#define _Included_messageapi_structs - -#include - -/** - * @author Ryan Berkheimer - */ - -struct list_item -{ - jobject jitem; -}; - -struct val_list -{ - int count; - jobject jlist; -}; - -struct response -{ - jobject jresponse; -}; - -struct request -{ - jobject jrequest; -}; - -struct condition -{ - jobject jcondition; -}; - -struct condition_list -{ - int count; - struct condition **conditions; -}; -struct val -{ - jobject jvalue; -}; - -struct field -{ - jobject jfield; -}; - -struct field_list -{ - int count; - struct field **fields; -}; - -struct packet -{ - jobject jpacket; -}; - -struct record -{ - jobject jrecord; -}; - -struct rejection_list -{ - int count; - jobject jrejections; -}; -struct rejection -{ - jobject jrejection; -}; - -struct record_list -{ - int count; - jobject jrecords; -}; - - -struct string_list -{ - int count; - int max_length; - char **strings; -}; - -struct classifier -{ - char* key; - char* val; -}; - -#endif \ No newline at end of file diff --git a/src/c/main/structs/messageapi_structs.h b/src/c/main/structs/messageapi_structs.h new file mode 100644 index 0000000000000000000000000000000000000000..f05ff1b46f7676342ea03424ff10b650c8635c11 --- /dev/null +++ b/src/c/main/structs/messageapi_structs.h @@ -0,0 +1,123 @@ + +#ifndef _Included_messageapi_structs +#define _Included_messageapi_structs + +#include + +/** + * @author Ryan Berkheimer + */ + +typedef struct map_val +{ + jobject jval; +} map_val; + +typedef struct val_map +{ + jobject jmap; +} val_map; + +typedef struct list_item +{ + jobject jitem; +} list_item; + +typedef struct val_list +{ + int count; + jobject jlist; +} val_list; + +typedef struct session +{ + jlong sessionLib; +} session; + +typedef struct transformation +{ + jobject jtransformation; +} transformation; + +typedef struct transformation_map +{ + jobject jtransformation_map; +} transformation_map; + +typedef struct response +{ + jobject jresponse; +} response; + +typedef struct request +{ + jobject jrequest; +} request; + +typedef struct condition +{ + jobject jcondition; +} condition; + +typedef struct condition_list +{ + int count; + struct condition **conditions; +} condition_list; +typedef struct val +{ + jobject jvalue; +} val; + +typedef struct field +{ + jobject jfield; +} field; + +typedef struct field_list +{ + int count; + struct field **fields; +} field_list; + +typedef struct packet +{ + jobject jpacket; +} packet; + +typedef struct record +{ + jobject jrecord; +} record; + +typedef struct rejection_list +{ + int count; + jobject jrejections; +} rejection_list; +typedef struct rejection +{ + jobject jrejection; +} rejection; + +typedef struct record_list +{ + int count; + jobject jrecords; +} record_list; + + +typedef struct string_list +{ + int count; + int max_length; + char **strings; +} string_list; + +typedef struct classifier +{ + char* key; + char* val; +} classifier; + +#endif \ No newline at end of file diff --git a/src/c/test/endpoints/demoendpointlibrary/gov_noaa_messageapi_endpoints_NativeEndpoint.h b/src/c/main/wrappers/endpoint/gov_noaa_messageapi_endpoints_NativeEndpoint.h similarity index 100% rename from src/c/test/endpoints/demoendpointlibrary/gov_noaa_messageapi_endpoints_NativeEndpoint.h rename to src/c/main/wrappers/endpoint/gov_noaa_messageapi_endpoints_NativeEndpoint.h diff --git a/src/c/main/wrappers/transformation/gov_noaa_messageapi_transformations_NativeTransformation.h b/src/c/main/wrappers/transformation/gov_noaa_messageapi_transformations_NativeTransformation.h new file mode 100644 index 0000000000000000000000000000000000000000..f4294a209a46810bac4df701589ee91a903f8d84 --- /dev/null +++ b/src/c/main/wrappers/transformation/gov_noaa_messageapi_transformations_NativeTransformation.h @@ -0,0 +1,37 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class gov_noaa_messageapi_transformations_NativeTransformation */ + +#ifndef _Included_gov_noaa_messageapi_transformations_NativeTransformation +#define _Included_gov_noaa_messageapi_transformations_NativeTransformation +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: gov_noaa_messageapi_transformations_NativeTransformation + * Method: process + * Signature: (J)Ljava/util/List; + */ +JNIEXPORT jobject JNICALL Java_gov_noaa_messageapi_transformations_NativeTransformation_process + (JNIEnv *, jobject, jlong); + +/* + * Class: gov_noaa_messageapi_transformations_NativeTransformation + * Method: create + * Signature: (Ljava/util/Map;)J + */ +JNIEXPORT jlong JNICALL Java_gov_noaa_messageapi_transformations_NativeTransformation_create + (JNIEnv *, jobject, jobject); + +/* + * Class: gov_noaa_messageapi_transformations_NativeTransformation + * Method: release + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_gov_noaa_messageapi_transformations_NativeTransformation_release + (JNIEnv *, jobject, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/c/test/endpoints/demoendpointlibrary/EndpointWrapper.c b/src/c/test/endpoints/endpoint_lib/EndpointWrapper.c similarity index 73% rename from src/c/test/endpoints/demoendpointlibrary/EndpointWrapper.c rename to src/c/test/endpoints/endpoint_lib/EndpointWrapper.c index c3b655b5c643afdf3978678c10171ce2094e22e0..136b1a388cc43cd3ea3c9c81b5500b082f6f2527 100644 --- a/src/c/test/endpoints/demoendpointlibrary/EndpointWrapper.c +++ b/src/c/test/endpoints/endpoint_lib/EndpointWrapper.c @@ -14,22 +14,22 @@ JNIEXPORT jobject JNICALL Java_gov_noaa_messageapi_endpoints_NativeEndpoint_proc { printf("In our test!\n"); printf("Hello, World\n"); - struct record_list* default_record_list = getRecords(message); + record_list* default_record_list = getRecords(message); //struct record_list* classifier_record_list = getRecordsByClassifier(message, "color", "blue"); //struct record_list* collection_record_list = getRecordsByCollection(message, "gold"); //struct record_list* transformation_record_list = getRecordsByTransformation(message, "combine-colors"); printf("Record count: %d\n", default_record_list->count); - struct string_list* default_field_name_list = getFieldIds(message, getRecord(message, default_record_list, 0)); + string_list* default_field_name_list = getFieldIds(message, getRecord(message, default_record_list, 0)); printf("Field name count: %d\n", default_field_name_list->count); printf("Length of longest field name: %d\n", default_field_name_list->max_length); for (int i = 0; i < default_field_name_list->count; i++) { printf("Field name: %s\n", default_field_name_list->strings[i]); } fflush(stdout); - struct field *testField = getField(message, getRecord(message, default_record_list, 0), "initial-value"); - struct field *testField2 = getField(message, getRecord(message, default_record_list, 0), "string-test"); - struct field *testField3 = getField(message, getRecord(message, default_record_list, 0), "int-list-test"); - struct field *testField4 = getField(message, getRecord(message, default_record_list, 0), "null-test"); + field *testField = getField(message, getRecord(message, default_record_list, 0), "initial-value"); + field *testField2 = getField(message, getRecord(message, default_record_list, 0), "string-test"); + field *testField3 = getField(message, getRecord(message, default_record_list, 0), "int-list-test"); + field *testField4 = getField(message, getRecord(message, default_record_list, 0), "null-test"); const char *testFieldId = getFieldId(message, testField); const char *testFieldId2 = getFieldId(message, testField2); const char *testFieldId3 = getFieldId(message, testField3); @@ -53,10 +53,11 @@ JNIEXPORT jobject JNICALL Java_gov_noaa_messageapi_endpoints_NativeEndpoint_proc printf("Field integer value is %d\n", integerFieldValue); const char *stringFieldValue = getFieldStringVal(message, testField2); printf("Field string value 2 is: %s\n", stringFieldValue); - struct val_list *val_list = getFieldListVal(message, testField3); - printf("Field value 3 (list) length is: %d\n", val_list->count); - for (int i = 0; i < val_list->count; i++) { - printf("Field value 3, element %d, is: %d\n", i, getIntItem(message, val_list, i)); + val_list *fieldList = getFieldListVal(message, testField3); + printf("Field value 3 (list) length is: %d\n", fieldList->count); + for (int i = 0; i < fieldList->count; i++) + { + printf("Field value 3, element %d, is: %d\n", i, getIntItem(message, fieldList, i)); } fflush(stdout); if (getFieldIsNull(message, testField4)) { @@ -65,8 +66,8 @@ JNIEXPORT jobject JNICALL Java_gov_noaa_messageapi_endpoints_NativeEndpoint_proc printf("Field val 4 has a value!\n"); } fflush(stdout); - struct record *returnRecord = createRecord(message); - struct string_list *fieldIds = getFieldIds(message, returnRecord); + record *returnRecord = createRecord(message); + string_list *fieldIds = getFieldIds(message, returnRecord); printf("field ids for return field follow. \n"); for (int i=0; i < fieldIds->count; i++) { printf("Field name: %s\n", fieldIds->strings[i]); @@ -81,17 +82,17 @@ JNIEXPORT jobject JNICALL Java_gov_noaa_messageapi_endpoints_NativeEndpoint_proc } } fflush(stdout); - printf("Creating a string list..\n"); - struct val_list *return_val_list = createList(message); - addStringItem(message, return_val_list, "first element of our string!"); - addStringItem(message, return_val_list, "second element of our string!!"); + printf("Creating a value list to hold strings..\n"); + val_list *returnList = createList(message); + addStringItem(message, returnList, "first element of our string!"); + addStringItem(message, returnList, "second element of our string!!"); printf("Created a string list.\n"); - setFieldListVal(message, getField(message, returnRecord, "return-list"), return_val_list); - printf("First value added to the return-list field: %s\n", getStringItem(message, return_val_list, 0)); - printf("Second value added to the return-list field: %s\n", getStringItem(message, return_val_list, 1)); + setFieldListVal(message, getField(message, returnRecord, "return-list"), returnList); + printf("First value added to the return-list field: %s\n", getStringItem(message, returnList, 0)); + printf("Second value added to the return-list field: %s\n", getStringItem(message, returnList, 1)); printf("Added the string list to the return record. Should have two elements, see above.\n"); fflush(stdout); - struct packet* packet = createPacket(message); + packet* packet = createPacket(message); addPacketRecord(message, packet, returnRecord); printf("Leaving our C test!"); fflush(stdout); diff --git a/src/c/test/sessions/demosession/DemoSession.c b/src/c/test/sessions/demosession/DemoSession.c deleted file mode 100644 index 07fdb95e0a01587b237e9a10413baf78bd484d20..0000000000000000000000000000000000000000 --- a/src/c/test/sessions/demosession/DemoSession.c +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include -#include "messageapi_structs.h" -#include "MessageApiSessionLib.h" - -int main(int argc, char **argv) -{ - JavaVM *vm; - JNIEnv *env; - JavaVMInitArgs vm_args; - jint res; - jclass cls; - jmethodID mid; - jstring jstr; - jobjectArray main_args; - - //vm_args.version = JNI_V - vm_args.nOptions = 0; - res = JNI_CreateJavaVM(&vm, (void **)&env, &vm_args); - if (res != JNI_OK) - { - printf("Failed to create Java VMn"); - return 1; - } - - cls = (*env)->FindClass(env, "Main"); - if (cls == NULL) - { - printf("Failed to find Main classn"); - return 1; - } - - mid = (*env)->GetStaticMethodID(env, cls, "main", "([Ljava/lang/String;)V"); - if (mid == NULL) - { - printf("Failed to find main functionn"); - return 1; - } - - jstr = (*env)->NewStringUTF(env, ""); - main_args = (*env)->NewObjectArray(env, 1, (*env)->FindClass(env, "java/lang/String"), jstr); - (*env)->CallStaticVoidMethod(env, cls, mid, main_args); - - return 0; -} \ No newline at end of file diff --git a/src/c/test/sessions/session_demo/SessionDemo.c b/src/c/test/sessions/session_demo/SessionDemo.c new file mode 100644 index 0000000000000000000000000000000000000000..b2c3b755e08478cbe395331744810969a71efc6f --- /dev/null +++ b/src/c/test/sessions/session_demo/SessionDemo.c @@ -0,0 +1,82 @@ +#include +#include +#include "messageapi_structs.h" +#include "MessageApiSessionLib.h" + +int main(int argc, char **argv) +{ + puts("In our native session demo test!\n"); + puts("Hello, World\n"); + fflush(stdout); + + session *session = createSession("/workspaces/messageapi/resources/test/file-reader-native/manifest.json"); + + puts("Successfully created session."); + fflush(stdout); + + request *request1 = createRequest(session); + + puts("Successfully created a request."); + fflush(stdout); + + record *record1 = createRequestRecord(session, request1); + + //record *record2 = createRequestRecord(session, request1); + + puts("Successfully created a request record."); + fflush(stdout); + + field *field1 = getField(session, record1, "file-path"); + + puts("Successfully retrieved the file-path field from the request record."); + fflush(stdout); + + setFieldStringVal(session, field1, "/workspaces/messageapi/resources/test/inputs/file-reader/simpletextfile"); + + puts(getFieldStringVal(session, field1)); + fflush(stdout); + + puts("Successfully set the field string value for the file-path field from the request record."); + fflush(stdout); + + record_list *session_records = createRecordList(session); + + addRecord(session, session_records, record1); + + //setRequestRecords(session, request1, session_records); + + record_list *request_records = getRequestRecords(session, request1); + printf("Request record count: %d\n", request_records->count); + fflush(stdout); + + response *response = submitRequest(session, request1); + + puts("Response completion status right after submission:"); + fputs(isComplete(session, response) ? "true" : "false", stdout); + puts(""); + fflush(stdout); + + puts("Successfully submitted the request."); + fflush(stdout); + + puts(getFieldStringVal(session, field1)); + fflush(stdout); + + while (!isComplete(session, response)) {} + + puts("Successfully returned from the request."); + fflush(stdout); + + //puts(getFieldStringVal(session, field1)); + //fflush(stdout); + + record_list *response_records = getResponseRecords(session, response); + rejection_list *response_rejections = getResponseRejections(session, response); + printf("Record count: %d\n", response_records->count); + printf("Rejection count: %d\n", response_rejections->count); + fflush(stdout); + + //releaseSession(session); + + return 0; +} \ No newline at end of file diff --git a/src/c/test/transformations/transformation_lib/TransformationWrapper.c b/src/c/test/transformations/transformation_lib/TransformationWrapper.c new file mode 100644 index 0000000000000000000000000000000000000000..ad8319fa63e63406732c8f054346619cb1c01290 --- /dev/null +++ b/src/c/test/transformations/transformation_lib/TransformationWrapper.c @@ -0,0 +1,23 @@ +#include +#include +#include "messageapi_structs.h" +#include "MessageApiTransformationLib.h" +#include "gov_noaa_messageapi_transformations_NativeTransformation.h" + +/* + * Class: gov_noaa_messageapi_transformations_NativeTransformation + * Method: process + * Signature: (Ljava/lang/Map;)Ljava/lang/List; + * @author Ryan Berkheimer + */ +JNIEXPORT jobject JNICALL Java_gov_noaa_messageapi_transformations_NativeTransformation_process(JNIEnv *env, jobject transformation, jlong message) + { + printf("In our transformation test!\n"); + printf("Hello, World\n"); + fflush(stdout); + record_list *records = getRecords(message, "test_key"); + printf("Record count: %d\n", records->count); + fflush(stdout); + return records->jrecords; + } + diff --git a/src/cpp/main/common/MessageApiEndpoint.cpp b/src/cpp/main/api/endpoint/MessageApiEndpoint.cpp similarity index 91% rename from src/cpp/main/common/MessageApiEndpoint.cpp rename to src/cpp/main/api/endpoint/MessageApiEndpoint.cpp index ed9bfe005b27d1b7cfe0023d9efe7366973b3b22..d83d0f6aad1a41c27885f0c9121194bd9bdc289e 100644 --- a/src/cpp/main/common/MessageApiEndpoint.cpp +++ b/src/cpp/main/api/endpoint/MessageApiEndpoint.cpp @@ -19,12 +19,13 @@ MessageApiEndpoint::MessageApiEndpoint(JNIEnv *env, jobject jendpoint, jobject j this->typeUtils = new TypeUtils(this->jvm); this->listUtils = new ListUtils(this->jvm, typeUtils); + this->mapUtils = new MapUtils(this->jvm, typeUtils); this->endpointUtils = new EndpointUtils(this->jvm, this->endpoint, this->typeUtils, this->listUtils); this->protocolRecordUtils = new ProtocolRecordUtils(this->jvm, this->protocolRecord, this->typeUtils, this->listUtils); this->recordUtils = new RecordUtils(this->jvm, this->typeUtils, this->listUtils); this->rejectionUtils = new RejectionUtils(this->jvm, this->typeUtils, this->listUtils); - this->fieldUtils = new FieldUtils(this->jvm, this->typeUtils, this->listUtils); - this->conditionUtils = new ConditionUtils(this->jvm, this->typeUtils, this->listUtils); + this->fieldUtils = new FieldUtils(this->jvm, this->typeUtils, this->listUtils, this->mapUtils); + this->conditionUtils = new ConditionUtils(this->jvm, this->typeUtils, this->listUtils, this->mapUtils); this->packetUtils = new PacketUtils(this->jvm, this->listUtils); } @@ -41,6 +42,7 @@ MessageApiEndpoint::~MessageApiEndpoint() delete this->conditionUtils; delete this->packetUtils; delete this->listUtils; + delete this->mapUtils; delete this->typeUtils; this->jvm->DeleteGlobalRef(this->endpoint); this->jvm->DeleteGlobalRef(this->protocolRecord); @@ -91,6 +93,11 @@ ListUtils *MessageApiEndpoint::getListUtils() return this->listUtils; } +MapUtils *MessageApiEndpoint::getMapUtils() +{ + return this->mapUtils; +} + TypeUtils *MessageApiEndpoint::getTypeUtils() { return this->typeUtils; diff --git a/src/cpp/main/common/MessageApiEndpoint.h b/src/cpp/main/api/endpoint/MessageApiEndpoint.h similarity index 96% rename from src/cpp/main/common/MessageApiEndpoint.h rename to src/cpp/main/api/endpoint/MessageApiEndpoint.h index 6265bb6252d727982459766f7fb2755b11fc7f84..e3a435f9ea26fd7d725f5fa77d8f5b38ce8fe086 100644 --- a/src/cpp/main/common/MessageApiEndpoint.h +++ b/src/cpp/main/api/endpoint/MessageApiEndpoint.h @@ -1,4 +1,3 @@ - #ifndef _Included_MessageApiEndpoint #define _Included_MessageApiEndpoint @@ -11,6 +10,7 @@ #include #include "JniUtils.h" +#include "MapUtils.h" #include "ListUtils.h" #include "EndpointUtils.h" #include "ProtocolRecordUtils.h" @@ -47,6 +47,7 @@ public: ConditionUtils *getConditionUtils(); PacketUtils *getPacketUtils(); ListUtils *getListUtils(); + MapUtils *getMapUtils(); TypeUtils *getTypeUtils(); private : @@ -64,6 +65,7 @@ private : PacketUtils *packetUtils; TypeUtils *typeUtils; ListUtils *listUtils; + MapUtils *mapUtils; }; diff --git a/src/cpp/main/api/session/MessageApiSession.cpp b/src/cpp/main/api/session/MessageApiSession.cpp new file mode 100644 index 0000000000000000000000000000000000000000..63f46f7ad0d2c0de29d8abf81478143594ea56a4 --- /dev/null +++ b/src/cpp/main/api/session/MessageApiSession.cpp @@ -0,0 +1,110 @@ +#include "MessageApiSession.h" + +#include +#include +#include +#include +#include +#include + +/** +Constructor for the MessageApiSession object. Takes a JNI environment pointer and a session context (this refers to +the instantiated java session object). +*/ +MessageApiSession::MessageApiSession(JNIEnv *env, jobject session) +{ + this->jvm = env; + this->session = this->jvm->NewGlobalRef(session); + this->typeUtils = new TypeUtils(this->jvm); + this->listUtils = new ListUtils(this->jvm, typeUtils); + this->mapUtils = new MapUtils(this->jvm, typeUtils); + this->sessionUtils = new SessionUtils(this->jvm, this->session); + this->requestUtils = new RequestUtils(this->jvm, this->typeUtils, this->listUtils); + this->responseUtils = new ResponseUtils(this->jvm, this->typeUtils, this->listUtils); + this->recordUtils = new RecordUtils(this->jvm, this->typeUtils, this->listUtils); + this->rejectionUtils = new RejectionUtils(this->jvm, this->typeUtils, this->listUtils); + this->fieldUtils = new FieldUtils(this->jvm, this->typeUtils, this->listUtils, this->mapUtils); + this->conditionUtils = new ConditionUtils(this->jvm, this->typeUtils, this->listUtils, this->mapUtils); + this->packetUtils = new PacketUtils(this->jvm, this->listUtils); +} + +MessageApiSession::~MessageApiSession() +{ + try + { + delete this->sessionUtils; + delete this->requestUtils; + delete this->responseUtils; + delete this->recordUtils; + delete this->rejectionUtils; + delete this->fieldUtils; + delete this->conditionUtils; + delete this->packetUtils; + delete this->listUtils; + delete this->mapUtils; + delete this->typeUtils; + this->jvm->DeleteGlobalRef(this->session); + } + catch (const std::exception &e) + { + std::cout << e.what(); + } +} + +SessionUtils *MessageApiSession::getSessionUtils() +{ + return this->sessionUtils; +} + +RequestUtils *MessageApiSession::getRequestUtils() +{ + return this->requestUtils; +} + +ResponseUtils *MessageApiSession::getResponseUtils() +{ + return this->responseUtils; +} + +RecordUtils *MessageApiSession::getRecordUtils() +{ + return this->recordUtils; +} + +RejectionUtils *MessageApiSession::getRejectionUtils() +{ + return this->rejectionUtils; +} + +FieldUtils *MessageApiSession::getFieldUtils() +{ + return this->fieldUtils; +} + +ConditionUtils *MessageApiSession::getConditionUtils() +{ + return this->conditionUtils; +} + +PacketUtils *MessageApiSession::getPacketUtils() +{ + return this->packetUtils; +} + +ListUtils *MessageApiSession::getListUtils() +{ + return this->listUtils; +} + +MapUtils *MessageApiSession::getMapUtils() +{ + return this->mapUtils; +} + +TypeUtils *MessageApiSession::getTypeUtils() +{ + return this->typeUtils; +} + + + diff --git a/src/cpp/main/api/session/MessageApiSession.h b/src/cpp/main/api/session/MessageApiSession.h new file mode 100644 index 0000000000000000000000000000000000000000..9eac29b60a705d105bce3f36e49b0757d3f420e9 --- /dev/null +++ b/src/cpp/main/api/session/MessageApiSession.h @@ -0,0 +1,78 @@ +#ifndef _Included_MessageApiSession +#define _Included_MessageApiSession + +#include +#include +#include "messageapi_structs.h" + +#ifdef __cplusplus +#include +#include + +#include "JniUtils.h" +#include "TypeUtils.h" +#include "MapUtils.h" +#include "ListUtils.h" +#include "SessionUtils.h" +#include "RequestUtils.h" +#include "ResponseUtils.h" +#include "RecordUtils.h" +#include "RejectionUtils.h" +#include "FieldUtils.h" +#include "ConditionUtils.h" +#include "PacketUtils.h" + +/** + * @author Ryan Berkheimer + */ +class MessageApiSession +{ + +public: + /*Default constructor*/ + MessageApiSession(JNIEnv *javaEnv, jobject jSession); + /*Default destructor*/ + ~MessageApiSession(); + + /*Utils Accessors*/ + SessionUtils *getSessionUtils(); + RequestUtils *getRequestUtils(); + ResponseUtils *getResponseUtils(); + RecordUtils *getRecordUtils(); + RejectionUtils *getRejectionUtils(); + FieldUtils *getFieldUtils(); + ConditionUtils *getConditionUtils(); + PacketUtils *getPacketUtils(); + ListUtils *getListUtils(); + MapUtils *getMapUtils(); + TypeUtils *getTypeUtils(); + +private : + /*Global References*/ + JNIEnv *jvm; + jobject session; + + SessionUtils *sessionUtils; + RequestUtils *requestUtils; + ResponseUtils *responseUtils; + RecordUtils *recordUtils; + RejectionUtils *rejectionUtils; + FieldUtils *fieldUtils; + ConditionUtils *conditionUtils; + PacketUtils *packetUtils; + TypeUtils *typeUtils; + ListUtils *listUtils; + MapUtils *mapUtils; + +}; + +extern "C" +{ + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/cpp/main/api/transformation/MessageApiTransformation.cpp b/src/cpp/main/api/transformation/MessageApiTransformation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..87d8c3d81f3a48e73ef815a80ccfbb0080ace71c --- /dev/null +++ b/src/cpp/main/api/transformation/MessageApiTransformation.cpp @@ -0,0 +1,100 @@ +#include "MessageApiTransformation.h" + +#include +#include +#include +#include +#include +#include + +/** +Constructor for the MessageApiTransformation object. Takes a JNI environment pointer, a transformation context (this refers to +the transformation class that's instantiating the object), and a transformation record which holds containers of records. +*/ +MessageApiTransformation::MessageApiTransformation(JNIEnv *env, jobject jtransformation, jobject jTransformationMap) +{ + this->jvm = env; + this->transformation = this->jvm->NewGlobalRef(jtransformation); + this->transformationMap = this->jvm->NewGlobalRef(jTransformationMap); + + this->typeUtils = new TypeUtils(this->jvm); + this->listUtils = new ListUtils(this->jvm, typeUtils); + this->mapUtils = new MapUtils(this->jvm, typeUtils); + this->transformationUtils = new TransformationUtils(this->jvm, this->transformation, this->transformationMap, this->typeUtils, this->mapUtils, this->listUtils); + this->recordUtils = new RecordUtils(this->jvm, this->typeUtils, this->listUtils); + this->rejectionUtils = new RejectionUtils(this->jvm, this->typeUtils, this->listUtils); + this->fieldUtils = new FieldUtils(this->jvm, this->typeUtils, this->listUtils, this->mapUtils); + this->conditionUtils = new ConditionUtils(this->jvm, this->typeUtils, this->listUtils, this->mapUtils); + this->packetUtils = new PacketUtils(this->jvm, this->listUtils); + +} + +MessageApiTransformation::~MessageApiTransformation() +{ + try + { + delete this->transformationUtils; + delete this->recordUtils; + delete this->rejectionUtils; + delete this->fieldUtils; + delete this->conditionUtils; + delete this->packetUtils; + delete this->listUtils; + delete this->mapUtils; + delete this->typeUtils; + this->jvm->DeleteGlobalRef(this->transformation); + this->jvm->DeleteGlobalRef(this->transformationMap); + } + catch (const std::exception &e) + { + std::cout << e.what(); + } +} + +TransformationUtils *MessageApiTransformation::getTransformationUtils() +{ + return this->transformationUtils; +} + +RecordUtils *MessageApiTransformation::getRecordUtils() +{ + return this->recordUtils; +} + +RejectionUtils *MessageApiTransformation::getRejectionUtils() +{ + return this->rejectionUtils; +} + +FieldUtils *MessageApiTransformation::getFieldUtils() +{ + return this->fieldUtils; +} + +ConditionUtils *MessageApiTransformation::getConditionUtils() +{ + return this->conditionUtils; +} + +PacketUtils *MessageApiTransformation::getPacketUtils() +{ + return this->packetUtils; +} + +ListUtils *MessageApiTransformation::getListUtils() +{ + return this->listUtils; +} + +MapUtils *MessageApiTransformation::getMapUtils() +{ + return this->mapUtils; +} + +TypeUtils *MessageApiTransformation::getTypeUtils() +{ + return this->typeUtils; +} + + + diff --git a/src/cpp/main/api/transformation/MessageApiTransformation.h b/src/cpp/main/api/transformation/MessageApiTransformation.h new file mode 100644 index 0000000000000000000000000000000000000000..dc1a0ea5d67a571d6b35185320e58c53335162fc --- /dev/null +++ b/src/cpp/main/api/transformation/MessageApiTransformation.h @@ -0,0 +1,84 @@ +#ifndef _Included_MessageApiTransformation +#define _Included_MessageApiTransformation + +#include +#include +#include "messageapi_structs.h" + +#ifdef __cplusplus +#include +#include + +#include "JniUtils.h" +#include "MapUtils.h" +#include "ListUtils.h" +#include "TransformationUtils.h" +#include "RecordUtils.h" +#include "RejectionUtils.h" +#include "FieldUtils.h" +#include "ConditionUtils.h" +#include "PacketUtils.h" + +/** + * This is the header for the MessageApiTransformation class - this class is the native side facility + * for doing transformation processing and communicating back with the java side. This class holds + * three private vars - a pointer to the jvm where the call originated from, a pointer to the + * transformation class instance (jobject), and a pointer to the map that holds data for + * this transformation to process as a jobject. + * + * The map contains keys that each hold a list of records. These records are immutable, meaning + * they can be modified however necessary without affecting other transformations or other threads + * within the computation. + * + * To the user of the MessageApiTransformation library in the native side, + * they will see the entire library as a single jlong. This jlong holds a pointer to this class, + * making it easier for implementors to ignore most of the details of implementation. + * @author Ryan Berkheimer + */ +class MessageApiTransformation +{ + +public: + /*Default constructor/destructors*/ + MessageApiTransformation(JNIEnv* javaEnv, jobject jTransformation, jobject jTransformationMap); + ~MessageApiTransformation(); + + /*Utils Accessors*/ + TransformationUtils *getTransformationUtils(); + RecordUtils *getRecordUtils(); + RejectionUtils *getRejectionUtils(); + FieldUtils *getFieldUtils(); + ConditionUtils *getConditionUtils(); + PacketUtils *getPacketUtils(); + ListUtils *getListUtils(); + MapUtils *getMapUtils(); + TypeUtils *getTypeUtils(); + +private : + /*Global References*/ + JNIEnv *jvm; + jobject transformation; + jobject transformationMap; + + TransformationUtils *transformationUtils; + RecordUtils *recordUtils; + RejectionUtils *rejectionUtils; + FieldUtils *fieldUtils; + ConditionUtils *conditionUtils; + PacketUtils *packetUtils; + TypeUtils *typeUtils; + ListUtils *listUtils; + MapUtils *mapUtils; + +}; + +extern "C" +{ + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/cpp/main/common/MessageApiEndpointLib.h b/src/cpp/main/common/MessageApiEndpointLib.h deleted file mode 100644 index f3fb04515274bf3ef604cb2d5b44915063ed4ab8..0000000000000000000000000000000000000000 --- a/src/cpp/main/common/MessageApiEndpointLib.h +++ /dev/null @@ -1,139 +0,0 @@ -#include - -/** - * @author Ryan Berkheimer - */ -#ifdef __cplusplus -extern "C" -{ -#endif - - /*Endpoint Methods*/ - struct record *getStateContainer(jlong message); - struct field_list *getDefaultFields(jlong message); - struct packet *createPacket(jlong message); - struct record *createRecord(jlong message); - struct rejection *createRejection(jlong message, struct record *record, const char *reason); - - /*Protocol Record Methods*/ - struct record_list *getRecords(jlong message); - struct record_list *getRecordsByCollection(jlong message, const char *collection); - struct record_list *getRecordsByTransformation(jlong message, const char *transformation); - struct record_list *getRecordsByUUID(jlong message, const char *uuid); - struct record_list *getRecordsByClassifier(jlong message, const char *key, const char *value); - struct record *getRecord(jlong message, struct record_list *recordList, int recordIndex); - - /*Record Methods*/ - struct record_list *createRecordList(jlong message); - void addRecord(jlong message, struct record_list *record_list, struct record *record); - - struct record *getRecordCopy(jlong message, struct record *record); - bool getRecordIsValid(jlong message, struct record *record); - - struct string_list *getFieldIds(jlong message, struct record *record); - struct field_list * getFields(jlong message, struct record *record); - struct field * getField(jlong message, struct record *record, const char *fieldId); - bool hasField(jlong message, struct record *record, const char *fieldId); - - struct string_list *getConditionIds(jlong message, struct record *record); - struct condition_list *getConditions(jlong message, struct record *record); - struct condition *getCondition(jlong message, struct record *record, const char *conditionId); - bool hasCondition(jlong message, struct record *record, const char *conditionId); - - /*Rejection Methods*/ - struct rejection_list *createRejectionList(jlong message); - void addRejection(jlong message, struct rejection_list *rejection_list, struct rejection *rejection); - struct rejection *getRejectionCopy(jlong message, struct rejection *rejection); - struct record *getRejectionRecord(jlong message, struct rejection *rejection); - struct string_list *getRejectionReasons(jlong message, struct rejection *rejection); - void addRejectionReason(jlong message, struct rejection *rejection, const char *reason); - - /*Field Methods*/ - const char *getFieldId(jlong message, struct field *field); - const char * getFieldType(jlong message, struct field *field); - bool getFieldIsValid(jlong message, struct field *field); - bool getFieldIsRequired(jlong message, struct field *field); - bool getFieldIsNull(jlong message, struct field *field); - struct val *getFieldVal(jlong message, struct field *field); - int getFieldIntVal(jlong message, struct field *field); - long getFieldLongVal(jlong message, struct field *field); - float getFieldFloatVal(jlong message, struct field *field); - double getFieldDoubleVal(jlong message, struct field *field); - signed char getFieldByteVal(jlong message, struct field *field); - const char *getFieldStringVal(jlong message, struct field *field); - bool getFieldBoolVal(jlong message, struct field *field); - short getFieldShortVal(jlong message, struct field *field); - struct val_list *getFieldListVal(jlong message, struct field *field); - void setFieldVal(jlong message, struct field *field, struct val *value); - void setFieldIntVal(jlong message, struct field *field, int value); - void setFieldLongVal(jlong message, struct field *field, long value); - void setFieldFloatVal(jlong message, struct field *field, float value); - void setFieldDoubleVal(jlong message, struct field *field, double value); - void setFieldByteVal(jlong message, struct field *field, signed char value); - void setFieldStringVal(jlong message, struct field *field, const char *value); - void setFieldBoolVal(jlong message, struct field *field, bool value); - void setFieldShortVal(jlong message, struct field *field, short value); - void setFieldListVal(jlong message, struct field *field, struct val_list *value); - - /*Condition Methods*/ - const char *getConditionId(jlong message, struct condition *condition); - const char *getConditionType(jlong message, struct condition *condition); - const char *getConditionOperator(jlong message, struct condition *condition); - bool getConditionIsNull(jlong message, struct condition *condition); - struct val *getConditionVal(jlong message, struct condition *condition); - int getConditionIntVal(jlong message, struct condition *condition); - long getConditionLongVal(jlong message, struct condition *condition); - float getConditionFloatVal(jlong message, struct condition *condition); - double getConditionDoubleVal(jlong message, struct condition *condition); - signed char getConditionByteVal(jlong message, struct condition *condition); - const char *getConditionStringVal(jlong message, struct condition *condition); - bool getConditionBoolVal(jlong message, struct condition *condition); - short getConditionShortVal(jlong message, struct condition *condition); - struct val_list *getConditionListVal(jlong message, struct condition *condition); - void setConditionVal(jlong message, struct condition *condition, struct val *value); - void setConditionIntVal(jlong message, struct condition *condition, int value); - void setConditionLongVal(jlong message, struct condition *condition, long value); - void setConditionFloatVal(jlong message, struct condition *condition, float value); - void setConditionDoubleVal(jlong message, struct condition *condition, double value); - void setConditionByteVal(jlong message, struct condition *condition, signed char value); - void setConditionStringVal(jlong message, struct condition *condition, const char *value); - void setConditionBoolVal(jlong message, struct condition *condition, bool value); - void setConditionShortVal(jlong message, struct condition *condition, short value); - void setConditionListVal(jlong message, struct condition *condition, struct val_list *value); - - /*List Utility Methods*/ - int getIntItem(jlong message, struct val_list *list, int index); - long getLongItem(jlong message, struct val_list *list, int index); - float getFloatItem(jlong message, struct val_list *list, int index); - double getDoubleItem(jlong message, struct val_list *list, int index); - signed char getByteItem(jlong message, struct val_list *list, int index); - const char *getStringItem(jlong message, struct val_list *list, int index); - bool getBoolItem(jlong message, struct val_list *list, int index); - short getShortItem(jlong message, struct val_list *list, int index); - struct list_item *getItem(jlong message, struct val_list *list, int index); - struct val_list *getListItem(jlong message, struct val_list *list, int index); - struct val_list *createList(jlong message); - void addItem(jlong message, struct val_list *list, struct list_item *item); - void addIntItem(jlong message, struct val_list *list, int val); - void addLongItem(jlong message, struct val_list *list, long val); - void addFloatItem(jlong message, struct val_list *list, float val); - void addDoubleItem(jlong message, struct val_list *list, double val); - void addByteItem(jlong message, struct val_list *list, signed char val); - void addStringItem(jlong message, struct val_list *list, const char *val); - void addBoolItem(jlong message, struct val_list *list, bool val); - void addShortItem(jlong message, struct val_list *list, short val); - void addListItem(jlong message, struct val_list *list, struct val_list *val); - - /*Packet Methods*/ - void addPacketRecord(jlong message, struct packet *packet, struct record *record); - void setPacketRecords(jlong message, struct packet *packet, struct record_list *records); - void addPacketRecords(jlong message, struct packet *packet, struct record_list *records); - void setPacketRejections(jlong message, struct packet *packet, struct rejection_list *rejections); - void addPacketRejection(jlong message, struct packet *packet, struct rejection *rejection); - void addPacketRejections(jlong message, struct packet *packet, struct rejection_list *rejections); - struct record_list *getPacketRecords(jlong message, struct packet *packet); - struct rejection_list *getPacketRejections(jlong message, struct packet *packet); - -#ifdef __cplusplus -} -#endif diff --git a/src/cpp/main/common/session/MessageApiSession.cpp b/src/cpp/main/common/session/MessageApiSession.cpp deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/cpp/main/common/session/MessageApiSession.h b/src/cpp/main/common/session/MessageApiSession.h deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/cpp/main/common/session/MessageApiSessionLib.cpp b/src/cpp/main/common/session/MessageApiSessionLib.cpp deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/cpp/main/common/session/MessageApiSessionLib.h b/src/cpp/main/common/session/MessageApiSessionLib.h deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/cpp/main/common/transformation/MessageApiTransformation.cpp b/src/cpp/main/common/transformation/MessageApiTransformation.cpp deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/cpp/main/common/transformation/MessageApiTransformation.h b/src/cpp/main/common/transformation/MessageApiTransformation.h deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/cpp/main/common/transformation/MessageApiTransformationLib.cpp b/src/cpp/main/common/transformation/MessageApiTransformationLib.cpp deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/cpp/main/common/transformation/MessageApiTransformationLib.h b/src/cpp/main/common/transformation/MessageApiTransformationLib.h deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/cpp/main/common/MessageApiEndpointLib.cpp b/src/cpp/main/libs/endpoint/MessageApiEndpointLib.cpp similarity index 51% rename from src/cpp/main/common/MessageApiEndpointLib.cpp rename to src/cpp/main/libs/endpoint/MessageApiEndpointLib.cpp index d684854c4bdc31facfe4e2efa57cba94fde2abfd..8eceb331b2a1b10fefb12076e57b5f02fda0a26b 100644 --- a/src/cpp/main/common/MessageApiEndpointLib.cpp +++ b/src/cpp/main/libs/endpoint/MessageApiEndpointLib.cpp @@ -1,8 +1,5 @@ -#include -#include -#include -#include "MessageApiEndpoint.h" #include "MessageApiEndpointLib.h" +#include "MessageApiEndpoint.h" #include "gov_noaa_messageapi_endpoints_NativeEndpoint.h" /** @@ -28,545 +25,718 @@ JNIEXPORT void JNICALL Java_gov_noaa_messageapi_endpoints_NativeEndpoint_release extern "C" { - struct record *getStateContainer(jlong message) + record *getStateContainer(jlong message) { return reinterpret_cast(message)->getEndpointUtils()->getStateContainer(); } - struct field_list *getDefaultFields(jlong message) + field_list *getDefaultFields(jlong message) { return reinterpret_cast(message)->getEndpointUtils()->getDefaultFields(); } - struct packet *createPacket(jlong message) + val_map *getConstructor(jlong message) + { + return reinterpret_cast(message)->getEndpointUtils()->getConstructor(); + } + + packet *createPacket(jlong message) { return reinterpret_cast(message)->getEndpointUtils()->createPacket(); } - struct record *createRecord(jlong message) + record *createRecord(jlong message) { return reinterpret_cast(message)->getEndpointUtils()->createRecord(); } - struct rejection *createRejection(jlong message, struct record *record, const char *reason) + rejection *createRejection(jlong message, record *record, const char *reason) { return reinterpret_cast(message)->getEndpointUtils()->createRejection(record, reason); } - struct record_list *getRecords(jlong message) + record_list *getRecords(jlong message) { return reinterpret_cast(message)->getProtocolRecordUtils()->getRecords("getRecords"); } - struct record_list *getRecordsByCollection(jlong message, const char *collectionId) + record_list *getRecordsByCollection(jlong message, const char *collectionId) { return reinterpret_cast(message)->getProtocolRecordUtils()->getRecords("getRecordsByCollection", collectionId); } - struct record_list *getRecordsByTransformation(jlong message, const char *transformationId) + record_list *getRecordsByTransformation(jlong message, const char *transformationId) { return reinterpret_cast(message)->getProtocolRecordUtils()->getRecords("getRecordsByTransformation", transformationId); } - struct record_list *getRecordsByUUID(jlong message, const char *uuid) + record_list *getRecordsByUUID(jlong message, const char *uuid) { return reinterpret_cast(message)->getProtocolRecordUtils()->getRecords("getRecordsByUUID", uuid); } - struct record_list *getRecordsByClassifier(jlong message, const char *classifierKey, const char *classifierValue) + record_list *getRecordsByClassifier(jlong message, const char *classifierKey, const char *classifierValue) { return reinterpret_cast(message)->getProtocolRecordUtils()->getRecords("getRecordsByClassifier", classifierKey, classifierValue); } - struct record_list *createRecordList(jlong message) + record_list *createRecordList(jlong message) { return reinterpret_cast(message)->getRecordUtils()->createRecordList(); } - void addRecord(jlong message, struct record_list *record_list, struct record *record) + void addRecord(jlong message, record_list *record_list, record *record) { return reinterpret_cast(message)->getRecordUtils()->addRecord(record_list, record); } - struct record *getRecord(jlong message, struct record_list *recordList, int recordIndex) + record *getRecord(jlong message, record_list *recordList, int recordIndex) { return reinterpret_cast(message)->getRecordUtils()->getRecord(recordList, recordIndex); } - struct record *getRecordCopy(jlong message, struct record *record) + record *getRecordCopy(jlong message, record *record) { return reinterpret_cast(message)->getRecordUtils()->getCopy(record); } - bool getRecordIsValid(jlong message, struct record *record) + bool getRecordIsValid(jlong message, record *record) { return reinterpret_cast(message)->getRecordUtils()->isValid(record); } - struct string_list *getFieldIds(jlong message, struct record *record) + string_list *getFieldIds(jlong message, record *record) { return reinterpret_cast(message)->getRecordUtils()->getFieldIds(record); } - struct field_list *getFields(jlong message, struct record *record) + field_list *getFields(jlong message, record *record) { return reinterpret_cast(message)->getRecordUtils()->getFields(record); } - struct field *getField(jlong message, struct record *record, const char* fieldId) + field *getField(jlong message, record *record, const char* fieldId) { return reinterpret_cast(message)->getRecordUtils()->getField(record, fieldId); } - bool hasField(jlong message, struct record *record, const char *fieldId) + bool hasField(jlong message, record *record, const char *fieldId) { return reinterpret_cast(message)->getRecordUtils()->hasField(record, fieldId); } - struct string_list *getConditionIds(jlong message, struct record *record) + string_list *getConditionIds(jlong message, record *record) { return reinterpret_cast(message)->getRecordUtils()->getConditionIds(record); } - struct condition_list *getConditions(jlong message, struct record *record) + condition_list *getConditions(jlong message, record *record) { return reinterpret_cast(message)->getRecordUtils()->getConditions(record); } - struct condition *getCondition(jlong message, struct record *record, const char *conditionId) + condition *getCondition(jlong message, record *record, const char *conditionId) { return reinterpret_cast(message)->getRecordUtils()->getCondition(record, conditionId); } - bool hasCondition(jlong message, struct record *record, const char *conditionId) + bool hasCondition(jlong message, record *record, const char *conditionId) { return reinterpret_cast(message)->getRecordUtils()->hasCondition(record, conditionId); } /*Field Methods*/ - const char *getFieldId(jlong message, struct field *field) + const char *getFieldId(jlong message, field *field) { return reinterpret_cast(message)->getFieldUtils()->getId(field); } - const char *getFieldType(jlong message, struct field *field) + const char *getFieldType(jlong message, field *field) { return reinterpret_cast(message)->getFieldUtils()->getType(field); } - bool getFieldIsValid(jlong message, struct field *field) + bool getFieldIsValid(jlong message, field *field) { return reinterpret_cast(message)->getFieldUtils()->isValid(field); } - bool getFieldIsRequired(jlong message, struct field *field) + bool getFieldIsRequired(jlong message, field *field) { return reinterpret_cast(message)->getFieldUtils()->isRequired(field); } - bool getFieldIsNull(jlong message, struct field *field) + bool getFieldIsNull(jlong message, field *field) { return reinterpret_cast(message)->getFieldUtils()->isNull(field); } - struct val *getFieldVal(jlong message, struct field *field) + val *getFieldVal(jlong message, field *field) { return reinterpret_cast(message)->getFieldUtils()->getVal(field); } - int getFieldIntVal(jlong message, struct field *field) + int getFieldIntVal(jlong message, field *field) { return reinterpret_cast(message)->getFieldUtils()->getIntVal(field); } - long getFieldLongVal(jlong message, struct field *field) + long getFieldLongVal(jlong message, field *field) { return reinterpret_cast(message)->getFieldUtils()->getLongVal(field); } - float getFieldFloatVal(jlong message, struct field *field) + float getFieldFloatVal(jlong message, field *field) { return reinterpret_cast(message)->getFieldUtils()->getFloatVal(field); } - double getFieldDoubleVal(jlong message, struct field *field) + double getFieldDoubleVal(jlong message, field *field) { return reinterpret_cast(message)->getFieldUtils()->getDoubleVal(field); } - signed char getFieldByteVal(jlong message, struct field *field) + signed char getFieldByteVal(jlong message, field *field) { return reinterpret_cast(message)->getFieldUtils()->getByteVal(field); } - const char *getFieldStringVal(jlong message, struct field *field) + const char *getFieldStringVal(jlong message, field *field) { return reinterpret_cast(message)->getFieldUtils()->getStringVal(field); } - bool getFieldBoolVal(jlong message, struct field *field) + bool getFieldBoolVal(jlong message, field *field) { return reinterpret_cast(message)->getFieldUtils()->getBoolVal(field); } - short getFieldShortVal(jlong message, struct field *field) + short getFieldShortVal(jlong message, field *field) { return reinterpret_cast(message)->getFieldUtils()->getShortVal(field); } - struct val_list *getFieldListVal(jlong message, struct field *field) + val_list *getFieldListVal(jlong message, field *field) { return reinterpret_cast(message)->getFieldUtils()->getListVal(field); } - void setFieldVal(jlong message, struct field *field, struct val *value) + val_map *getFieldMapVal(jlong message, field *field) + { + return reinterpret_cast(message)->getFieldUtils()->getMapVal(field); + } + + void setFieldVal(jlong message, field *field, val *value) { return reinterpret_cast(message)->getFieldUtils()->setVal(field, value); } - void setFieldIntVal(jlong message, struct field *field, int value) + void setFieldIntVal(jlong message, field *field, int value) { return reinterpret_cast(message)->getFieldUtils()->setIntVal(field, value); } - void setFieldLongVal(jlong message, struct field *field, long value) + void setFieldLongVal(jlong message, field *field, long value) { return reinterpret_cast(message)->getFieldUtils()->setLongVal(field, value); } - void setFieldFloatVal(jlong message, struct field *field, float value) + void setFieldFloatVal(jlong message, field *field, float value) { return reinterpret_cast(message)->getFieldUtils()->setFloatVal(field, value); } - void setFieldDoubleVal(jlong message, struct field *field, double value) + void setFieldDoubleVal(jlong message, field *field, double value) { return reinterpret_cast(message)->getFieldUtils()->setDoubleVal(field, value); } - void setFieldByteVal(jlong message, struct field *field, signed char value) + void setFieldByteVal(jlong message, field *field, signed char value) { return reinterpret_cast(message)->getFieldUtils()->setByteVal(field, value); } - void setFieldStringVal(jlong message, struct field *field, const char *value) + void setFieldStringVal(jlong message, field *field, const char *value) { return reinterpret_cast(message)->getFieldUtils()->setStringVal(field, value); } - void setFieldBoolVal(jlong message, struct field *field, bool value) + void setFieldBoolVal(jlong message, field *field, bool value) { return reinterpret_cast(message)->getFieldUtils()->setBoolVal(field, value); } - void setFieldShortVal(jlong message, struct field *field, short value) + void setFieldShortVal(jlong message, field *field, short value) { return reinterpret_cast(message)->getFieldUtils()->setShortVal(field, value); } - void setFieldListVal(jlong message, struct field *field, struct val_list *value) + void setFieldListVal(jlong message, field *field, val_list *value) { return reinterpret_cast(message)->getFieldUtils()->setListVal(field, value); } + void setFieldMapVal(jlong message, field *field, val_map *value) + { + return reinterpret_cast(message)->getFieldUtils()->setMapVal(field, value); + } + /*Condition Methods*/ - const char *getConditionId(jlong message, struct condition *condition) + const char *getConditionId(jlong message, condition *condition) { return reinterpret_cast(message)->getConditionUtils()->getId(condition); } - const char *getConditionType(jlong message, struct condition *condition) + const char *getConditionType(jlong message, condition *condition) { return reinterpret_cast(message)->getConditionUtils()->getType(condition); } - const char *getConditionOperator(jlong message, struct condition *condition) + const char *getConditionOperator(jlong message, condition *condition) { return reinterpret_cast(message)->getConditionUtils()->getOperator(condition); } - bool getConditionIsNull(jlong message, struct condition *condition) + bool getConditionIsNull(jlong message, condition *condition) { return reinterpret_cast(message)->getConditionUtils()->isNull(condition); } - struct val *getConditionVal(jlong message, struct condition *condition) + val *getConditionVal(jlong message, condition *condition) { return reinterpret_cast(message)->getConditionUtils()->getVal(condition); } - int getConditionIntVal(jlong message, struct condition *condition) + int getConditionIntVal(jlong message, condition *condition) { return reinterpret_cast(message)->getConditionUtils()->getIntVal(condition); } - long getConditionLongVal(jlong message, struct condition *condition) + long getConditionLongVal(jlong message, condition *condition) { return reinterpret_cast(message)->getConditionUtils()->getLongVal(condition); } - float getConditionFloatVal(jlong message, struct condition *condition) + float getConditionFloatVal(jlong message, condition *condition) { return reinterpret_cast(message)->getConditionUtils()->getFloatVal(condition); } - double getConditionDoubleVal(jlong message, struct condition *condition) + double getConditionDoubleVal(jlong message, condition *condition) { return reinterpret_cast(message)->getConditionUtils()->getDoubleVal(condition); } - signed char getConditionByteVal(jlong message, struct condition *condition) + signed char getConditionByteVal(jlong message, condition *condition) { return reinterpret_cast(message)->getConditionUtils()->getByteVal(condition); } - const char *getConditionStringVal(jlong message, struct condition *condition) + const char *getConditionStringVal(jlong message, condition *condition) { return reinterpret_cast(message)->getConditionUtils()->getStringVal(condition); } - bool getConditionBoolVal(jlong message, struct condition *condition) + bool getConditionBoolVal(jlong message, condition *condition) { return reinterpret_cast(message)->getConditionUtils()->getBoolVal(condition); } - short getConditionShortVal(jlong message, struct condition *condition) + short getConditionShortVal(jlong message, condition *condition) { return reinterpret_cast(message)->getConditionUtils()->getShortVal(condition); } - struct val_list *getConditionListVal(jlong message, struct condition *condition) + val_list *getConditionListVal(jlong message, condition *condition) { return reinterpret_cast(message)->getConditionUtils()->getListVal(condition); } - void setConditionVal(jlong message, struct condition *condition, struct val *value) + val_map *getConditionMapVal(jlong message, condition *condition) + { + return reinterpret_cast(message)->getConditionUtils()->getMapVal(condition); + } + + void setConditionVal(jlong message, condition *condition, val *value) { return reinterpret_cast(message)->getConditionUtils()->setVal(condition, value); } - void setConditionIntVal(jlong message, struct condition *condition, int value) + void setConditionIntVal(jlong message, condition *condition, int value) { return reinterpret_cast(message)->getConditionUtils()->setIntVal(condition, value); } - void setConditionLongVal(jlong message, struct condition *condition, long value) + void setConditionLongVal(jlong message, condition *condition, long value) { return reinterpret_cast(message)->getConditionUtils()->setLongVal(condition, value); } - void setConditionFloatVal(jlong message, struct condition *condition, float value) + void setConditionFloatVal(jlong message, condition *condition, float value) { return reinterpret_cast(message)->getConditionUtils()->setFloatVal(condition, value); } - void setConditionDoubleVal(jlong message, struct condition *condition, double value) + void setConditionDoubleVal(jlong message, condition *condition, double value) { return reinterpret_cast(message)->getConditionUtils()->setDoubleVal(condition, value); } - void setConditionByteVal(jlong message, struct condition *condition, signed char value) + void setConditionByteVal(jlong message, condition *condition, signed char value) { return reinterpret_cast(message)->getConditionUtils()->setByteVal(condition, value); } - void setConditionStringVal(jlong message, struct condition *condition, const char *value) + void setConditionStringVal(jlong message, condition *condition, const char *value) { return reinterpret_cast(message)->getConditionUtils()->setStringVal(condition, value); } - void setConditionBoolVal(jlong message, struct condition *condition, bool value) + void setConditionBoolVal(jlong message, condition *condition, bool value) { return reinterpret_cast(message)->getConditionUtils()->setBoolVal(condition, value); } - void setConditionShortVal(jlong message, struct condition *condition, short value) + void setConditionShortVal(jlong message, condition *condition, short value) { return reinterpret_cast(message)->getConditionUtils()->setShortVal(condition, value); } - void setConditionListVal(jlong message, struct condition *condition, struct val_list *value) + void setConditionListVal(jlong message, condition *condition, val_list *value) { return reinterpret_cast(message)->getConditionUtils()->setListVal(condition, value); } + void setConditionMapVal(jlong message, condition *condition, val_map *value) + { + return reinterpret_cast(message)->getConditionUtils()->setMapVal(condition, value); + } + /*List Utility Methods*/ - struct list_item *getItem(jlong message, struct val_list *list, int index) + list_item *getItem(jlong message, val_list *list, int index) { return reinterpret_cast(message)->getListUtils()->getItem(list, index); } - struct val_list *getListItem(jlong message, struct val_list *list, int index) + val_list *getListItem(jlong message, val_list *list, int index) { return reinterpret_cast(message)->getListUtils()->getListItem(list, index); } - int getIntItem(jlong message, struct val_list *list, int index) + val_map *getMapItem(jlong message, val_list *list, int index) + { + return reinterpret_cast(message)->getListUtils()->getMapItem(list, index); + } + + int getIntItem(jlong message, val_list *list, int index) { return reinterpret_cast(message)->getListUtils()->getIntItem(list, index); } - long getLongItem(jlong message, struct val_list *list, int index) + long getLongItem(jlong message, val_list *list, int index) { return reinterpret_cast(message)->getListUtils()->getLongItem(list, index); } - float getFloatItem(jlong message, struct val_list *list, int index) + float getFloatItem(jlong message, val_list *list, int index) { return reinterpret_cast(message)->getListUtils()->getFloatItem(list, index); } - double getDoubleItem(jlong message, struct val_list *list, int index) + double getDoubleItem(jlong message, val_list *list, int index) { return reinterpret_cast(message)->getListUtils()->getDoubleItem(list, index); } - signed char getByteItem(jlong message, struct val_list *list, int index) + signed char getByteItem(jlong message, val_list *list, int index) { return reinterpret_cast(message)->getListUtils()->getByteItem(list, index); } - const char *getStringItem(jlong message, struct val_list *list, int index) + const char *getStringItem(jlong message, val_list *list, int index) { return reinterpret_cast(message)->getListUtils()->getStringItem(list, index); } - bool getBoolItem(jlong message, struct val_list *list, int index) + bool getBoolItem(jlong message, val_list *list, int index) { return reinterpret_cast(message)->getListUtils()->getBoolItem(list, index); } - short getShortItem(jlong message, struct val_list *list, int index) + short getShortItem(jlong message, val_list *list, int index) { return reinterpret_cast(message)->getListUtils()->getShortItem(list, index); } - struct val_list *createList(jlong message) + val_list *createList(jlong message) { return reinterpret_cast(message)->getListUtils()->createList(); } - void addItem(jlong message, struct val_list *list, struct list_item *item) + void addItem(jlong message, val_list *list, list_item *item) { return reinterpret_cast(message)->getListUtils()->addItem(list, item); } - void addIntItem(jlong message, struct val_list *list, int val) + void addIntItem(jlong message, val_list *list, int val) { return reinterpret_cast(message)->getListUtils()->addIntItem(list, val); } - void addLongItem(jlong message, struct val_list *list, long val) + void addLongItem(jlong message, val_list *list, long val) { return reinterpret_cast(message)->getListUtils()->addLongItem(list, val); } - void addFloatItem(jlong message, struct val_list *list, float val) + void addFloatItem(jlong message, val_list *list, float val) { return reinterpret_cast(message)->getListUtils()->addFloatItem(list, val); } - void addDoubleItem(jlong message, struct val_list *list, double val) + void addDoubleItem(jlong message, val_list *list, double val) { return reinterpret_cast(message)->getListUtils()->addDoubleItem(list, val); } - void addByteItem(jlong message, struct val_list *list, signed char val) + void addByteItem(jlong message, val_list *list, signed char val) { return reinterpret_cast(message)->getListUtils()->addByteItem(list, val); } - void addStringItem(jlong message, struct val_list *list, const char *val) + void addStringItem(jlong message, val_list *list, const char *val) { return reinterpret_cast(message)->getListUtils()->addStringItem(list, val); } - void addBoolItem(jlong message, struct val_list *list, bool val) + void addBoolItem(jlong message, val_list *list, bool val) { return reinterpret_cast(message)->getListUtils()->addBoolItem(list, val); } - void addShortItem(jlong message, struct val_list *list, short val) + void addShortItem(jlong message, val_list *list, short val) { return reinterpret_cast(message)->getListUtils()->addShortItem(list, val); } - void addListItem(jlong message, struct val_list *list, struct val_list *val) + void addListItem(jlong message, val_list *list, val_list *val) { return reinterpret_cast(message)->getListUtils()->addListItem(list, val); } + void addMapItem(jlong message, val_list *list, val_map *val) + { + return reinterpret_cast(message)->getListUtils()->addMapItem(list, val); + } + + /*Map Utility Methods*/ + val_map *createMap(jlong message) + { + return reinterpret_cast(message)->getMapUtils()->createMap(); + } + + int getSize(jlong message, val_map *map) + { + return reinterpret_cast(message)->getMapUtils()->getSize(map); + } + + bool hasKey(jlong message, val_map *map, const char *key) + { + return reinterpret_cast(message)->getMapUtils()->hasKey(map, key); + } + + /*Map Value Retrieval Methods*/ + map_val *getVal(jlong message, val_map *map, const char *key) + { + return reinterpret_cast(message)->getMapUtils()->getVal(map, key); + } + + jobject getObjectVal(jlong message, val_map *map, const char *key) + { + return reinterpret_cast(message)->getMapUtils()->getObjectVal(map, key); + } + + int getIntVal(jlong message, val_map *map, const char *key) + { + return reinterpret_cast(message)->getMapUtils()->getIntVal(map, key); + } + + long getLongVal(jlong message, val_map *map, const char *key) + { + return reinterpret_cast(message)->getMapUtils()->getLongVal(map, key); + } + + float getFloatVal(jlong message, val_map *map, const char *key) + { + return reinterpret_cast(message)->getMapUtils()->getFloatVal(map, key); + } + + double getDoubleVal(jlong message, val_map *map, const char *key) + { + return reinterpret_cast(message)->getMapUtils()->getDoubleVal(map, key); + } + + signed char getByteVal(jlong message, val_map *map, const char *key) + { + return reinterpret_cast(message)->getMapUtils()->getByteVal(map, key); + } + + const char *getStringVal(jlong message, val_map *map, const char *key) + { + return reinterpret_cast(message)->getMapUtils()->getStringVal(map, key); + } + + bool getBoolVal(jlong message, val_map *map, const char *key) + { + return reinterpret_cast(message)->getMapUtils()->getBoolVal(map, key); + } + + short getShortVal(jlong message, val_map *map, const char *key) + { + return reinterpret_cast(message)->getMapUtils()->getShortVal(map, key); + } + + val_list *getListVal(jlong message, val_map *map, const char *key) + { + return reinterpret_cast(message)->getMapUtils()->getListVal(map, key); + } + + val_map *getMapVal(jlong message, val_map *map, const char *key) + { + return reinterpret_cast(message)->getMapUtils()->getMapVal(map, key); + } + + /*Insert or Update Methods*/ + void putVal(jlong message, val_map *map, const char *key, map_val *val) + { + return reinterpret_cast(message)->getMapUtils()->putVal(map, key, val); + } + + void putObjectVal(jlong message, val_map *map, const char *key, jobject val) + { + return reinterpret_cast(message)->getMapUtils()->putObjectVal(map, key, val); + } + + void putIntVal(jlong message, val_map *map, const char *key, int val) + { + return reinterpret_cast(message)->getMapUtils()->putIntVal(map, key, val); + } + + void putLongVal(jlong message, val_map *map, const char *key, long val) + { + return reinterpret_cast(message)->getMapUtils()->putLongVal(map, key, val); + } + + void putFloatVal(jlong message, val_map *map, const char *key, float val) + { + return reinterpret_cast(message)->getMapUtils()->putFloatVal(map, key, val); + } + + void putDoubleVal(jlong message, val_map *map, const char *key, double val) + { + return reinterpret_cast(message)->getMapUtils()->putDoubleVal(map, key, val); + } + + void putByteVal(jlong message, val_map *map, const char *key, signed char val) + { + return reinterpret_cast(message)->getMapUtils()->putByteVal(map, key, val); + } + + void putStringVal(jlong message, val_map *map, const char *key, const char *val) + { + return reinterpret_cast(message)->getMapUtils()->putStringVal(map, key, val); + } + + void putBoolVal(jlong message, val_map *map, const char *key, bool val) + { + return reinterpret_cast(message)->getMapUtils()->putBoolVal(map, key, val); + } + + void putShortVal(jlong message, val_map *map, const char *key, short val) + { + return reinterpret_cast(message)->getMapUtils()->putShortVal(map, key, val); + } + + void putListVal(jlong message, val_map *map, const char *key, val_list *val) + { + return reinterpret_cast(message)->getMapUtils()->putListVal(map, key, val); + } + + void putMapVal(jlong message, val_map *map, const char *key, val_map *val) + { + return reinterpret_cast(message)->getMapUtils()->putMapVal(map, key, val); + } + /*Rejection Utils*/ - struct rejection_list *createRejectionList(jlong message) + rejection_list *createRejectionList(jlong message) { return reinterpret_cast(message)->getRejectionUtils()->createRejectionList(); } - void addRejection(jlong message, struct rejection_list *rejection_list, struct rejection *rejection) + void addRejection(jlong message, rejection_list *rejection_list, rejection *rejection) { return reinterpret_cast(message)->getRejectionUtils()->addRejection(rejection_list, rejection); } - struct rejection *getRejectionCopy(jlong message, struct rejection *rejection) + rejection *getRejectionCopy(jlong message, rejection *rejection) { return reinterpret_cast(message)->getRejectionUtils()->getCopy(rejection); } - struct record *getRejectionRecord(jlong message, struct rejection *rejection) + record *getRejectionRecord(jlong message, rejection *rejection) { return reinterpret_cast(message)->getRejectionUtils()->getRecord(rejection); } - struct string_list *getRejectionReasons(jlong message, struct rejection *rejection) + string_list *getRejectionReasons(jlong message, rejection *rejection) { return reinterpret_cast(message)->getRejectionUtils()->getReasons(rejection); } - void addRejectionReason(jlong message, struct rejection *rejection, const char *reason) + void addRejectionReason(jlong message, rejection *rejection, const char *reason) { return reinterpret_cast(message)->getRejectionUtils()->addReason(rejection, reason); } /*Packet Utils*/ - void addPacketRecord(jlong message, struct packet *packet, struct record *record) + void addPacketRecord(jlong message, packet *packet, record *record) { return reinterpret_cast(message)->getPacketUtils()->addRecord(packet, record); } - void setPacketRecords(jlong message, struct packet *packet, struct record_list *records) + void setPacketRecords(jlong message, packet *packet, record_list *records) { return reinterpret_cast(message)->getPacketUtils()->setRecords(packet, records); } - void addPacketRecords(jlong message, struct packet *packet, struct record_list *records) + void addPacketRecords(jlong message, packet *packet, record_list *records) { return reinterpret_cast(message)->getPacketUtils()->addRecords(packet, records); } - void setPacketRejections(jlong message, struct packet *packet, struct rejection_list *rejections) + void setPacketRejections(jlong message, packet *packet, rejection_list *rejections) { return reinterpret_cast(message)->getPacketUtils()->setRejections(packet, rejections); } - void addPacketRejection(jlong message, struct packet *packet, struct rejection *rejection) + void addPacketRejection(jlong message, packet *packet, rejection *rejection) { return reinterpret_cast(message)->getPacketUtils()->addRejection(packet, rejection); } - void addPacketRejections(jlong message, struct packet *packet, struct rejection_list *rejections) + void addPacketRejections(jlong message, packet *packet, rejection_list *rejections) { return reinterpret_cast(message)->getPacketUtils()->addRejections(packet, rejections); } - struct record_list *getPacketRecords(jlong message, struct packet *packet) + record_list *getPacketRecords(jlong message, packet *packet) { return reinterpret_cast(message)->getPacketUtils()->getRecords(packet); } - struct rejection_list *getPacketRejections(jlong message, struct packet *packet) + rejection_list *getPacketRejections(jlong message, packet *packet) { return reinterpret_cast(message)->getPacketUtils()->getRejections(packet); } diff --git a/src/cpp/main/libs/endpoint/MessageApiEndpointLib.h b/src/cpp/main/libs/endpoint/MessageApiEndpointLib.h new file mode 100644 index 0000000000000000000000000000000000000000..7cc713fb6f1a9993720de4fbafb91713abe20fe5 --- /dev/null +++ b/src/cpp/main/libs/endpoint/MessageApiEndpointLib.h @@ -0,0 +1,186 @@ +#include +#include + +#include "messageapi_structs.h" + +/** + * @author Ryan Berkheimer + */ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*Endpoint Methods*/ + record *getStateContainer(jlong message); + field_list *getDefaultFields(jlong message); + val_map *getConstructor(jlong message); + packet *createPacket(jlong message); + record *createRecord(jlong message); + rejection *createRejection(jlong message, record *record, const char *reason); + + /*Protocol Record Methods*/ + record_list *getRecords(jlong message); + record_list *getRecordsByCollection(jlong message, const char *collection); + record_list *getRecordsByTransformation(jlong message, const char *transformation); + record_list *getRecordsByUUID(jlong message, const char *uuid); + record_list *getRecordsByClassifier(jlong message, const char *key, const char *value); + record *getRecord(jlong message, record_list *recordList, int recordIndex); + + /*Record Methods*/ + record_list *createRecordList(jlong message); + void addRecord(jlong message, record_list *record_list, record *record); + + record *getRecordCopy(jlong message, record *record); + bool getRecordIsValid(jlong message, record *record); + + string_list *getFieldIds(jlong message, record *record); + field_list * getFields(jlong message, record *record); + field * getField(jlong message, record *record, const char *fieldId); + bool hasField(jlong message, record *record, const char *fieldId); + + string_list *getConditionIds(jlong message, record *record); + condition_list *getConditions(jlong message, record *record); + condition *getCondition(jlong message, record *record, const char *conditionId); + bool hasCondition(jlong message, record *record, const char *conditionId); + + /*Rejection Methods*/ + rejection_list *createRejectionList(jlong message); + void addRejection(jlong message, rejection_list *rejection_list, rejection *rejection); + rejection *getRejectionCopy(jlong message, rejection *rejection); + record *getRejectionRecord(jlong message, rejection *rejection); + string_list *getRejectionReasons(jlong message, rejection *rejection); + void addRejectionReason(jlong message, rejection *rejection, const char *reason); + + /*Field Methods*/ + const char *getFieldId(jlong message, field *field); + const char * getFieldType(jlong message, field *field); + bool getFieldIsValid(jlong message, field *field); + bool getFieldIsRequired(jlong message, field *field); + bool getFieldIsNull(jlong message, field *field); + + val *getFieldVal(jlong message, field *field); + int getFieldIntVal(jlong message, field *field); + long getFieldLongVal(jlong message, field *field); + float getFieldFloatVal(jlong message, field *field); + double getFieldDoubleVal(jlong message, field *field); + signed char getFieldByteVal(jlong message, field *field); + const char *getFieldStringVal(jlong message, field *field); + bool getFieldBoolVal(jlong message, field *field); + short getFieldShortVal(jlong message, field *field); + val_list *getFieldListVal(jlong message, field *field); + val_map *getFieldMapVal(jlong message, field *field); + + void setFieldVal(jlong message, field *field, val *value); + void setFieldIntVal(jlong message, field *field, int value); + void setFieldLongVal(jlong message, field *field, long value); + void setFieldFloatVal(jlong message, field *field, float value); + void setFieldDoubleVal(jlong message, field *field, double value); + void setFieldByteVal(jlong message, field *field, signed char value); + void setFieldStringVal(jlong message, field *field, const char *value); + void setFieldBoolVal(jlong message, field *field, bool value); + void setFieldShortVal(jlong message, field *field, short value); + void setFieldListVal(jlong message, field *field, val_list *value); + void setFieldMapVal(jlong message, field *field, val_map *value); + + /*Condition Methods*/ + const char *getConditionId(jlong message, condition *condition); + const char *getConditionType(jlong message, condition *condition); + const char *getConditionOperator(jlong message, condition *condition); + bool getConditionIsNull(jlong message, condition *condition); + + val *getConditionVal(jlong message, condition *condition); + int getConditionIntVal(jlong message, condition *condition); + long getConditionLongVal(jlong message, condition *condition); + float getConditionFloatVal(jlong message, condition *condition); + double getConditionDoubleVal(jlong message, condition *condition); + signed char getConditionByteVal(jlong message, condition *condition); + const char *getConditionStringVal(jlong message, condition *condition); + bool getConditionBoolVal(jlong message, condition *condition); + short getConditionShortVal(jlong message, condition *condition); + val_list *getConditionListVal(jlong message, condition *condition); + val_map *getConditionMapVal(jlong message, condition *condition); + + void setConditionVal(jlong message, condition *condition, val *value); + void setConditionIntVal(jlong message, condition *condition, int value); + void setConditionLongVal(jlong message, condition *condition, long value); + void setConditionFloatVal(jlong message, condition *condition, float value); + void setConditionDoubleVal(jlong message, condition *condition, double value); + void setConditionByteVal(jlong message, condition *condition, signed char value); + void setConditionStringVal(jlong message, condition *condition, const char *value); + void setConditionBoolVal(jlong message, condition *condition, bool value); + void setConditionShortVal(jlong message, condition *condition, short value); + void setConditionListVal(jlong message, condition *condition, val_list *value); + void setConditionMapVal(jlong message, condition *condition, val_map *value); + + /*List Utility Methods*/ + int getIntItem(jlong message, val_list *list, int index); + long getLongItem(jlong message, val_list *list, int index); + float getFloatItem(jlong message, val_list *list, int index); + double getDoubleItem(jlong message, val_list *list, int index); + signed char getByteItem(jlong message, val_list *list, int index); + const char *getStringItem(jlong message, val_list *list, int index); + bool getBoolItem(jlong message, val_list *list, int index); + short getShortItem(jlong message, val_list *list, int index); + list_item *getItem(jlong message, val_list *list, int index); + val_list *getListItem(jlong message, val_list *list, int index); + val_map *getMapItem(jlong message, val_list *list, int index); + val_list *createList(jlong message); + void addItem(jlong message, val_list *list, list_item *item); + void addIntItem(jlong message, val_list *list, int val); + void addLongItem(jlong message, val_list *list, long val); + void addFloatItem(jlong message, val_list *list, float val); + void addDoubleItem(jlong message, val_list *list, double val); + void addByteItem(jlong message, val_list *list, signed char val); + void addStringItem(jlong message, val_list *list, const char *val); + void addBoolItem(jlong message, val_list *list, bool val); + void addShortItem(jlong message, val_list *list, short val); + void addListItem(jlong message, val_list *list, val_list *val); + void addMapItem(jlong message, val_list *list, val_map *map); + + /*Map Utility Methods*/ + val_map *createMap(jlong message); + int getSize(jlong message, val_map *map); + bool hasKey(jlong message, val_map *map, const char *key); + + /*Map Value Retrieval Methods*/ + map_val *getVal(jlong message, val_map *map, const char *key); + jobject getObjectVal(jlong message, val_map *map, const char *key); + int getIntVal(jlong message, val_map *map, const char *key); + long getLongVal(jlong message, val_map *map, const char *key); + float getFloatVal(jlong message, val_map *map, const char *key); + double getDoubleVal(jlong message, val_map *map, const char *key); + signed char getByteVal(jlong message, val_map *map, const char *key); + const char *getStringVal(jlong message, val_map *map, const char *key); + bool getBoolVal(jlong message, val_map *map, const char *key); + short getShortVal(jlong message, val_map *map, const char *key); + val_list *getListVal(jlong message, val_map *map, const char *key); + val_map *getMapVal(jlong message, val_map *map, const char *key); + + /*Insert or Update Methods*/ + void putVal(jlong message, val_map *map, const char *key, map_val *val); + void putObjectVal(jlong message, val_map *map, const char *key, jobject val); + void putIntVal(jlong message, val_map *map, const char *key, int val); + void putLongVal(jlong message, val_map *map, const char *key, long val); + void putFloatVal(jlong message, val_map *map, const char *key, float val); + void putDoubleVal(jlong message, val_map *map, const char *key, double val); + void putByteVal(jlong message, val_map *map, const char *key, signed char val); + void putStringVal(jlong message, val_map *map, const char *key, const char *val); + void putBoolVal(jlong message, val_map *map, const char *key, bool val); + void putShortVal(jlong message, val_map *map, const char *key, short val); + void putListVal(jlong message, val_map *map, const char *key, val_list *val); + void putMapVal(jlong message, val_map *map, const char *key, val_map *val); + + /*Packet Methods*/ + void addPacketRecord(jlong message, packet *packet, record *record); + void setPacketRecords(jlong message, packet *packet, record_list *records); + void addPacketRecords(jlong message, packet *packet, record_list *records); + void setPacketRejections(jlong message, packet *packet, rejection_list *rejections); + void addPacketRejection(jlong message, packet *packet, rejection *rejection); + void addPacketRejections(jlong message, packet *packet, rejection_list *rejections); + record_list *getPacketRecords(jlong message, packet *packet); + rejection_list *getPacketRejections(jlong message, packet *packet); + +#ifdef __cplusplus +} +#endif diff --git a/src/cpp/main/libs/session/MessageApiSessionLib.cpp b/src/cpp/main/libs/session/MessageApiSessionLib.cpp new file mode 100644 index 0000000000000000000000000000000000000000..77dbca810394047835c8ddcab42659976b5b6989 --- /dev/null +++ b/src/cpp/main/libs/session/MessageApiSessionLib.cpp @@ -0,0 +1,798 @@ +#include "MessageApiSessionLib.h" + +extern "C" +{ + /** + * Creates the default session. + */ + session *createSession(const char *spec) + { + JavaVM *vm; + JNIEnv *env; + JavaVMInitArgs vm_args; + JavaVMOption options[1]; + jint jvmCreationStatus; + char classpath[5000]; + strcpy(classpath, "-Djava.class.path="); + strcat(classpath, getenv("CLASSPATH")); + options[0].optionString = classpath; + vm_args.version = JNI_VERSION_1_8; + vm_args.options = options; + vm_args.nOptions = 1; + vm_args.ignoreUnrecognized = JNI_TRUE; + + jvmCreationStatus = JNI_CreateJavaVM(&vm, (void **)&env, &vm_args); + + if (jvmCreationStatus != JNI_OK) + { + puts("Failed to create Java VM."); + fflush(stdout); + return NULL; + } + + jclass sessionClass = JniUtils::getNamedClass(env, "gov/noaa/messageapi/sessions/DefaultSession"); + jmethodID createSessionMethodId = JniUtils::getMethod(env, sessionClass, "", "(Ljava/lang/String;)V", false); + jstring jSpec = env->NewStringUTF(spec); + jobject jSession = env->NewObject(sessionClass, createSessionMethodId, jSpec); + jlong sessionLib = reinterpret_cast(new MessageApiSession(env, jSession)); + struct session *session = (struct session *)malloc(sizeof(session) + sizeof(sessionLib)); + session->sessionLib = sessionLib; + env->DeleteLocalRef(jSession); + env->DeleteLocalRef(jSpec); + env->DeleteLocalRef(sessionClass); + return session; + } + + /** + * Deletes the C++ pointer (calls C++ destructor)) that references the object created during session construction. + * This call is NOT made automatically, as the session is created Natively, so this should be called manually. + */ + void releaseSession(session *session) + { + delete reinterpret_cast(session->sessionLib); + free(session); + } + + request *createRequest(session *session) + { + return reinterpret_cast(session->sessionLib)->getSessionUtils()->createRequest(); + } + + /* Request methods */ + record *createRequestRecord(session *session, request *request) + { + return reinterpret_cast(session->sessionLib)->getRequestUtils()->createRecord(request); + } + + request *getRequestCopy(session *session, request *request) + { + return reinterpret_cast(session->sessionLib)->getRequestUtils()->getCopy(request); + } + + request *getRequestCopyComponents(session *session, request *request, val_list *copy_components) + { + return reinterpret_cast(session->sessionLib)->getRequestUtils()->getCopy(request, copy_components); + } + + const char *getRequestType(session *session, request *request) + { + return reinterpret_cast(session->sessionLib)->getRequestUtils()->getType(request); + } + + record_list *getRequestRecords(session *session, request *request) + { + return reinterpret_cast(session->sessionLib)->getRequestUtils()->getRecords(request); + } + + record *getRequestRecord(session *session, request *request) + { + return reinterpret_cast(session->sessionLib)->getRequestUtils()->getRequestRecord(request); + } + + void setRequestRecords(session *session, request *request, record_list *records) + { + return reinterpret_cast(session->sessionLib)->getRequestUtils()->setRecords(request, records); + } + + response *submitRequest(session *session, request *request) + { + return reinterpret_cast(session->sessionLib)->getRequestUtils()->submitRequest(request); + } + + /* Response methods */ + bool isComplete(session *session, response *response) + { + return reinterpret_cast(session->sessionLib)->getResponseUtils()->isComplete(response); + } + + request *getResponseRequest(session *session, response *response) + { + return reinterpret_cast(session->sessionLib)->getResponseUtils()->getRequest(response); + } + + rejection_list *getResponseRejections(session *session, response *response) + { + return reinterpret_cast(session->sessionLib)->getResponseUtils()->getRejections(response); + } + + record_list *getResponseRecords(session *session, response *response) + { + return reinterpret_cast(session->sessionLib)->getResponseUtils()->getRecords(response); + } + + void setResponseRejections(session *session, response *response, rejection_list *rejections) + { + return reinterpret_cast(session->sessionLib)->getResponseUtils()->setRejections(response, rejections); + } + + void setResponseRecords(session *session, response *response, record_list *records) + { + return reinterpret_cast(session->sessionLib)->getResponseUtils()->setRecords(response, records); + } + + void setComplete(session *session, response *response, bool isComplete) + { + return reinterpret_cast(session->sessionLib)->getResponseUtils()->setComplete(response, isComplete); + } + + record_list *createRecordList(session *session) + { + return reinterpret_cast(session->sessionLib)->getRecordUtils()->createRecordList(); + } + + void addRecord(session *session, record_list *record_list, record *record) + { + return reinterpret_cast(session->sessionLib)->getRecordUtils()->addRecord(record_list, record); + } + + record *getRecord(session *session, record_list *recordList, int recordIndex) + { + return reinterpret_cast(session->sessionLib)->getRecordUtils()->getRecord(recordList, recordIndex); + } + + record *getRecordCopy(session *session, record *record) + { + return reinterpret_cast(session->sessionLib)->getRecordUtils()->getCopy(record); + } + + bool getRecordIsValid(session *session, record *record) + { + return reinterpret_cast(session->sessionLib)->getRecordUtils()->isValid(record); + } + + string_list *getFieldIds(session *session, record *record) + { + return reinterpret_cast(session->sessionLib)->getRecordUtils()->getFieldIds(record); + } + + field_list *getFields(session *session, record *record) + { + return reinterpret_cast(session->sessionLib)->getRecordUtils()->getFields(record); + } + + field *getField(session *session, record *record, const char* fieldId) + { + return reinterpret_cast(session->sessionLib)->getRecordUtils()->getField(record, fieldId); + } + + bool hasField(session *session, record *record, const char *fieldId) + { + return reinterpret_cast(session->sessionLib)->getRecordUtils()->hasField(record, fieldId); + } + + string_list *getConditionIds(session *session, record *record) + { + return reinterpret_cast(session->sessionLib)->getRecordUtils()->getConditionIds(record); + } + + condition_list *getConditions(session *session, record *record) + { + return reinterpret_cast(session->sessionLib)->getRecordUtils()->getConditions(record); + } + + condition *getCondition(session *session, record *record, const char *conditionId) + { + return reinterpret_cast(session->sessionLib)->getRecordUtils()->getCondition(record, conditionId); + } + + bool hasCondition(session *session, record *record, const char *conditionId) + { + return reinterpret_cast(session->sessionLib)->getRecordUtils()->hasCondition(record, conditionId); + } + + /*Field Methods*/ + + const char *getFieldId(session *session, field *field) + { + return reinterpret_cast(session->sessionLib)->getFieldUtils()->getId(field); + } + + const char *getFieldType(session *session, field *field) + { + return reinterpret_cast(session->sessionLib)->getFieldUtils()->getType(field); + } + + bool getFieldIsValid(session *session, field *field) + { + return reinterpret_cast(session->sessionLib)->getFieldUtils()->isValid(field); + } + + bool getFieldIsRequired(session *session, field *field) + { + return reinterpret_cast(session->sessionLib)->getFieldUtils()->isRequired(field); + } + + bool getFieldIsNull(session *session, field *field) + { + return reinterpret_cast(session->sessionLib)->getFieldUtils()->isNull(field); + } + + val *getFieldVal(session *session, field *field) + { + return reinterpret_cast(session->sessionLib)->getFieldUtils()->getVal(field); + } + + int getFieldIntVal(session *session, field *field) + { + return reinterpret_cast(session->sessionLib)->getFieldUtils()->getIntVal(field); + } + + long getFieldLongVal(session *session, field *field) + { + return reinterpret_cast(session->sessionLib)->getFieldUtils()->getLongVal(field); + } + + float getFieldFloatVal(session *session, field *field) + { + return reinterpret_cast(session->sessionLib)->getFieldUtils()->getFloatVal(field); + } + + double getFieldDoubleVal(session *session, field *field) + { + return reinterpret_cast(session->sessionLib)->getFieldUtils()->getDoubleVal(field); + } + + signed char getFieldByteVal(session *session, field *field) + { + return reinterpret_cast(session->sessionLib)->getFieldUtils()->getByteVal(field); + } + + const char *getFieldStringVal(session *session, field *field) + { + return reinterpret_cast(session->sessionLib)->getFieldUtils()->getStringVal(field); + } + + bool getFieldBoolVal(session *session, field *field) + { + return reinterpret_cast(session->sessionLib)->getFieldUtils()->getBoolVal(field); + } + + short getFieldShortVal(session *session, field *field) + { + return reinterpret_cast(session->sessionLib)->getFieldUtils()->getShortVal(field); + } + + val_list *getFieldListVal(session *session, field *field) + { + return reinterpret_cast(session->sessionLib)->getFieldUtils()->getListVal(field); + } + + val_map *getFieldMapVal(session *session, field *field) + { + return reinterpret_cast(session->sessionLib)->getFieldUtils()->getMapVal(field); + } + + void setFieldVal(session *session, field *field, val *value) + { + return reinterpret_cast(session->sessionLib)->getFieldUtils()->setVal(field, value); + } + + void setFieldIntVal(session *session, field *field, int value) + { + return reinterpret_cast(session->sessionLib)->getFieldUtils()->setIntVal(field, value); + } + + void setFieldLongVal(session *session, field *field, long value) + { + return reinterpret_cast(session->sessionLib)->getFieldUtils()->setLongVal(field, value); + } + + void setFieldFloatVal(session *session, field *field, float value) + { + return reinterpret_cast(session->sessionLib)->getFieldUtils()->setFloatVal(field, value); + } + + void setFieldDoubleVal(session *session, field *field, double value) + { + return reinterpret_cast(session->sessionLib)->getFieldUtils()->setDoubleVal(field, value); + } + + void setFieldByteVal(session *session, field *field, signed char value) + { + return reinterpret_cast(session->sessionLib)->getFieldUtils()->setByteVal(field, value); + } + + void setFieldStringVal(session *session, field *field, const char *value) + { + return reinterpret_cast(session->sessionLib)->getFieldUtils()->setStringVal(field, value); + } + + void setFieldBoolVal(session *session, field *field, bool value) + { + return reinterpret_cast(session->sessionLib)->getFieldUtils()->setBoolVal(field, value); + } + + void setFieldShortVal(session *session, field *field, short value) + { + return reinterpret_cast(session->sessionLib)->getFieldUtils()->setShortVal(field, value); + } + + void setFieldListVal(session *session, field *field, val_list *value) + { + return reinterpret_cast(session->sessionLib)->getFieldUtils()->setListVal(field, value); + } + + void setFieldMapVal(session *session, field *field, val_map *value) + { + return reinterpret_cast(session->sessionLib)->getFieldUtils()->setMapVal(field, value); + } + + /*Condition Methods*/ + + const char *getConditionId(session *session, condition *condition) + { + return reinterpret_cast(session->sessionLib)->getConditionUtils()->getId(condition); + } + + const char *getConditionType(session *session, condition *condition) + { + return reinterpret_cast(session->sessionLib)->getConditionUtils()->getType(condition); + } + + const char *getConditionOperator(session *session, condition *condition) + { + return reinterpret_cast(session->sessionLib)->getConditionUtils()->getOperator(condition); + } + + bool getConditionIsNull(session *session, condition *condition) + { + return reinterpret_cast(session->sessionLib)->getConditionUtils()->isNull(condition); + } + + val *getConditionVal(session *session, condition *condition) + { + return reinterpret_cast(session->sessionLib)->getConditionUtils()->getVal(condition); + } + + int getConditionIntVal(session *session, condition *condition) + { + return reinterpret_cast(session->sessionLib)->getConditionUtils()->getIntVal(condition); + } + + long getConditionLongVal(session *session, condition *condition) + { + return reinterpret_cast(session->sessionLib)->getConditionUtils()->getLongVal(condition); + } + + float getConditionFloatVal(session *session, condition *condition) + { + return reinterpret_cast(session->sessionLib)->getConditionUtils()->getFloatVal(condition); + } + + double getConditionDoubleVal(session *session, condition *condition) + { + return reinterpret_cast(session->sessionLib)->getConditionUtils()->getDoubleVal(condition); + } + + signed char getConditionByteVal(session *session, condition *condition) + { + return reinterpret_cast(session->sessionLib)->getConditionUtils()->getByteVal(condition); + } + + const char *getConditionStringVal(session *session, condition *condition) + { + return reinterpret_cast(session->sessionLib)->getConditionUtils()->getStringVal(condition); + } + + bool getConditionBoolVal(session *session, condition *condition) + { + return reinterpret_cast(session->sessionLib)->getConditionUtils()->getBoolVal(condition); + } + + short getConditionShortVal(session *session, condition *condition) + { + return reinterpret_cast(session->sessionLib)->getConditionUtils()->getShortVal(condition); + } + + val_list *getConditionListVal(session *session, condition *condition) + { + return reinterpret_cast(session->sessionLib)->getConditionUtils()->getListVal(condition); + } + + val_map *getConditionMapVal(session *session, condition *condition) + { + return reinterpret_cast(session->sessionLib)->getConditionUtils()->getMapVal(condition); + } + + void setConditionVal(session *session, condition *condition, val *value) + { + return reinterpret_cast(session->sessionLib)->getConditionUtils()->setVal(condition, value); + } + + void setConditionIntVal(session *session, condition *condition, int value) + { + return reinterpret_cast(session->sessionLib)->getConditionUtils()->setIntVal(condition, value); + } + + void setConditionLongVal(session *session, condition *condition, long value) + { + return reinterpret_cast(session->sessionLib)->getConditionUtils()->setLongVal(condition, value); + } + + void setConditionFloatVal(session *session, condition *condition, float value) + { + return reinterpret_cast(session->sessionLib)->getConditionUtils()->setFloatVal(condition, value); + } + + void setConditionDoubleVal(session *session, condition *condition, double value) + { + return reinterpret_cast(session->sessionLib)->getConditionUtils()->setDoubleVal(condition, value); + } + + void setConditionByteVal(session *session, condition *condition, signed char value) + { + return reinterpret_cast(session->sessionLib)->getConditionUtils()->setByteVal(condition, value); + } + + void setConditionStringVal(session *session, condition *condition, const char *value) + { + return reinterpret_cast(session->sessionLib)->getConditionUtils()->setStringVal(condition, value); + } + + void setConditionBoolVal(session *session, condition *condition, bool value) + { + return reinterpret_cast(session->sessionLib)->getConditionUtils()->setBoolVal(condition, value); + } + + void setConditionShortVal(session *session, condition *condition, short value) + { + return reinterpret_cast(session->sessionLib)->getConditionUtils()->setShortVal(condition, value); + } + + void setConditionListVal(session *session, condition *condition, val_list *value) + { + return reinterpret_cast(session->sessionLib)->getConditionUtils()->setListVal(condition, value); + } + + void setConditionMapVal(session *session, condition *condition, val_map *value) + { + return reinterpret_cast(session->sessionLib)->getConditionUtils()->setMapVal(condition, value); + } + + /*List Utility Methods*/ + + list_item *getItem(session *session, val_list *list, int index) + { + return reinterpret_cast(session->sessionLib)->getListUtils()->getItem(list, index); + } + + val_list *getListItem(session *session, val_list *list, int index) + { + return reinterpret_cast(session->sessionLib)->getListUtils()->getListItem(list, index); + } + + val_map *getMapItem(session *session, val_list *list, int index) + { + return reinterpret_cast(session->sessionLib)->getListUtils()->getMapItem(list, index); + } + + int getIntItem(session *session, val_list *list, int index) + { + return reinterpret_cast(session->sessionLib)->getListUtils()->getIntItem(list, index); + } + + long getLongItem(session *session, val_list *list, int index) + { + return reinterpret_cast(session->sessionLib)->getListUtils()->getLongItem(list, index); + } + + float getFloatItem(session *session, val_list *list, int index) + { + return reinterpret_cast(session->sessionLib)->getListUtils()->getFloatItem(list, index); + } + + double getDoubleItem(session *session, val_list *list, int index) + { + return reinterpret_cast(session->sessionLib)->getListUtils()->getDoubleItem(list, index); + } + + signed char getByteItem(session *session, val_list *list, int index) + { + return reinterpret_cast(session->sessionLib)->getListUtils()->getByteItem(list, index); + } + + const char *getStringItem(session *session, val_list *list, int index) + { + return reinterpret_cast(session->sessionLib)->getListUtils()->getStringItem(list, index); + } + + bool getBoolItem(session *session, val_list *list, int index) + { + return reinterpret_cast(session->sessionLib)->getListUtils()->getBoolItem(list, index); + } + + short getShortItem(session *session, val_list *list, int index) + { + return reinterpret_cast(session->sessionLib)->getListUtils()->getShortItem(list, index); + } + + val_list *createList(session *session) + { + return reinterpret_cast(session->sessionLib)->getListUtils()->createList(); + } + + void addItem(session *session, val_list *list, list_item *item) + { + return reinterpret_cast(session->sessionLib)->getListUtils()->addItem(list, item); + } + + void addIntItem(session *session, val_list *list, int val) + { + return reinterpret_cast(session->sessionLib)->getListUtils()->addIntItem(list, val); + } + + void addLongItem(session *session, val_list *list, long val) + { + return reinterpret_cast(session->sessionLib)->getListUtils()->addLongItem(list, val); + } + + void addFloatItem(session *session, val_list *list, float val) + { + return reinterpret_cast(session->sessionLib)->getListUtils()->addFloatItem(list, val); + } + + void addDoubleItem(session *session, val_list *list, double val) + { + return reinterpret_cast(session->sessionLib)->getListUtils()->addDoubleItem(list, val); + } + + void addByteItem(session *session, val_list *list, signed char val) + { + return reinterpret_cast(session->sessionLib)->getListUtils()->addByteItem(list, val); + } + + void addStringItem(session *session, val_list *list, const char *val) + { + return reinterpret_cast(session->sessionLib)->getListUtils()->addStringItem(list, val); + } + + void addBoolItem(session *session, val_list *list, bool val) + { + return reinterpret_cast(session->sessionLib)->getListUtils()->addBoolItem(list, val); + } + + void addShortItem(session *session, val_list *list, short val) + { + return reinterpret_cast(session->sessionLib)->getListUtils()->addShortItem(list, val); + } + + void addListItem(session *session, val_list *list, val_list *val) + { + return reinterpret_cast(session->sessionLib)->getListUtils()->addListItem(list, val); + } + + void addMapItem(session *session, val_list *list, val_map *val) + { + return reinterpret_cast(session->sessionLib)->getListUtils()->addMapItem(list, val); + } + + /*Map Utility Methods*/ + val_map *createMap(session *session) + { + return reinterpret_cast(session->sessionLib)->getMapUtils()->createMap(); + } + + int getSize(session *session, val_map *map) + { + return reinterpret_cast(session->sessionLib)->getMapUtils()->getSize(map); + } + + bool hasKey(session *session, val_map *map, const char *key) + { + return reinterpret_cast(session->sessionLib)->getMapUtils()->hasKey(map, key); + } + + /*Map Value Retrieval Methods*/ + map_val *getVal(session *session, val_map *map, const char *key) + { + return reinterpret_cast(session->sessionLib)->getMapUtils()->getVal(map, key); + } + + jobject getObjectVal(session *session, val_map *map, const char *key) + { + return reinterpret_cast(session->sessionLib)->getMapUtils()->getObjectVal(map, key); + } + + int getIntVal(session *session, val_map *map, const char *key) + { + return reinterpret_cast(session->sessionLib)->getMapUtils()->getIntVal(map, key); + } + + long getLongVal(session *session, val_map *map, const char *key) + { + return reinterpret_cast(session->sessionLib)->getMapUtils()->getLongVal(map, key); + } + + float getFloatVal(session *session, val_map *map, const char *key) + { + return reinterpret_cast(session->sessionLib)->getMapUtils()->getFloatVal(map, key); + } + + double getDoubleVal(session *session, val_map *map, const char *key) + { + return reinterpret_cast(session->sessionLib)->getMapUtils()->getDoubleVal(map, key); + } + + signed char getByteVal(session *session, val_map *map, const char *key) + { + return reinterpret_cast(session->sessionLib)->getMapUtils()->getByteVal(map, key); + } + + const char *getStringVal(session *session, val_map *map, const char *key) + { + return reinterpret_cast(session->sessionLib)->getMapUtils()->getStringVal(map, key); + } + + bool getBoolVal(session *session, val_map *map, const char *key) + { + return reinterpret_cast(session->sessionLib)->getMapUtils()->getBoolVal(map, key); + } + + short getShortVal(session *session, val_map *map, const char *key) + { + return reinterpret_cast(session->sessionLib)->getMapUtils()->getShortVal(map, key); + } + + val_list *getListVal(session *session, val_map *map, const char *key) + { + return reinterpret_cast(session->sessionLib)->getMapUtils()->getListVal(map, key); + } + + val_map *getMapVal(session *session, val_map *map, const char *key) + { + return reinterpret_cast(session->sessionLib)->getMapUtils()->getMapVal(map, key); + } + + /*Insert or Update Methods*/ + void putVal(session *session, val_map *map, const char *key, map_val *val) + { + return reinterpret_cast(session->sessionLib)->getMapUtils()->putVal(map, key, val); + } + + void putObjectVal(session *session, val_map *map, const char *key, jobject val) + { + return reinterpret_cast(session->sessionLib)->getMapUtils()->putObjectVal(map, key, val); + } + + void putIntVal(session *session, val_map *map, const char *key, int val) + { + return reinterpret_cast(session->sessionLib)->getMapUtils()->putIntVal(map, key, val); + } + + void putLongVal(session *session, val_map *map, const char *key, long val) + { + return reinterpret_cast(session->sessionLib)->getMapUtils()->putLongVal(map, key, val); + } + + void putFloatVal(session *session, val_map *map, const char *key, float val) + { + return reinterpret_cast(session->sessionLib)->getMapUtils()->putFloatVal(map, key, val); + } + + void putDoubleVal(session *session, val_map *map, const char *key, double val) + { + return reinterpret_cast(session->sessionLib)->getMapUtils()->putDoubleVal(map, key, val); + } + + void putByteVal(session *session, val_map *map, const char *key, signed char val) + { + return reinterpret_cast(session->sessionLib)->getMapUtils()->putByteVal(map, key, val); + } + + void putStringVal(session *session, val_map *map, const char *key, const char *val) + { + return reinterpret_cast(session->sessionLib)->getMapUtils()->putStringVal(map, key, val); + } + + void putBoolVal(session *session, val_map *map, const char *key, bool val) + { + return reinterpret_cast(session->sessionLib)->getMapUtils()->putBoolVal(map, key, val); + } + + void putShortVal(session *session, val_map *map, const char *key, short val) + { + return reinterpret_cast(session->sessionLib)->getMapUtils()->putShortVal(map, key, val); + } + + void putListVal(session *session, val_map *map, const char *key, val_list *val) + { + return reinterpret_cast(session->sessionLib)->getMapUtils()->putListVal(map, key, val); + } + + void putMapVal(session *session, val_map *map, const char *key, val_map *val) + { + return reinterpret_cast(session->sessionLib)->getMapUtils()->putMapVal(map, key, val); + } + + /*Rejection Utils*/ + rejection_list *createRejectionList(session *session) + { + return reinterpret_cast(session->sessionLib)->getRejectionUtils()->createRejectionList(); + } + + void addRejection(session *session, rejection_list *rejection_list, rejection *rejection) + { + return reinterpret_cast(session->sessionLib)->getRejectionUtils()->addRejection(rejection_list, rejection); + } + + rejection *getRejectionCopy(session *session, rejection *rejection) + { + return reinterpret_cast(session->sessionLib)->getRejectionUtils()->getCopy(rejection); + } + + record *getRejectionRecord(session *session, rejection *rejection) + { + return reinterpret_cast(session->sessionLib)->getRejectionUtils()->getRecord(rejection); + } + + string_list *getRejectionReasons(session *session, rejection *rejection) + { + return reinterpret_cast(session->sessionLib)->getRejectionUtils()->getReasons(rejection); + } + + void addRejectionReason(session *session, rejection *rejection, const char *reason) + { + return reinterpret_cast(session->sessionLib)->getRejectionUtils()->addReason(rejection, reason); + } + + /*Packet Utils*/ + void addPacketRecord(session *session, packet *packet, record *record) + { + return reinterpret_cast(session->sessionLib)->getPacketUtils()->addRecord(packet, record); + } + + void setPacketRecords(session *session, packet *packet, record_list *records) + { + return reinterpret_cast(session->sessionLib)->getPacketUtils()->setRecords(packet, records); + } + + void addPacketRecords(session *session, packet *packet, record_list *records) + { + return reinterpret_cast(session->sessionLib)->getPacketUtils()->addRecords(packet, records); + } + + void setPacketRejections(session *session, packet *packet, rejection_list *rejections) + { + return reinterpret_cast(session->sessionLib)->getPacketUtils()->setRejections(packet, rejections); + } + + void addPacketRejection(session *session, packet *packet, rejection *rejection) + { + return reinterpret_cast(session->sessionLib)->getPacketUtils()->addRejection(packet, rejection); + } + + void addPacketRejections(session *session, packet *packet, rejection_list *rejections) + { + return reinterpret_cast(session->sessionLib)->getPacketUtils()->addRejections(packet, rejections); + } + + record_list *getPacketRecords(session *session, packet *packet) + { + return reinterpret_cast(session->sessionLib)->getPacketUtils()->getRecords(packet); + } + + rejection_list *getPacketRejections(session *session, packet *packet) + { + return reinterpret_cast(session->sessionLib)->getPacketUtils()->getRejections(packet); + } +} \ No newline at end of file diff --git a/src/cpp/main/libs/session/MessageApiSessionLib.h b/src/cpp/main/libs/session/MessageApiSessionLib.h new file mode 100644 index 0000000000000000000000000000000000000000..f4ff14ff1ec918878316bbf9098895210870f3cd --- /dev/null +++ b/src/cpp/main/libs/session/MessageApiSessionLib.h @@ -0,0 +1,198 @@ +#include +#include +#include +#include + +#include "messageapi_structs.h" + +#include "JniUtils.h" +#include "MessageApiSession.h" +/** + * @author Ryan Berkheimer + */ +#ifdef __cplusplus +extern "C" +{ +#endif + + /* Session methods */ + extern session *createSession(const char* specPath); + extern void releaseSession(session *session); + extern request *createRequest(session *session); + + /* Request methods */ + extern record *createRequestRecord(session *session, request *request); + extern request *getRequestCopy(session *session, request *request); + extern request *getRequestCopyComponents(session *session, request *request, val_list *copy_components); + extern const char *getRequestType(session *session, request *request); + extern record_list *getRequestRecords(session *session, request *request); + extern record *getRequestRecord(session *session, request *request); + extern void setRequestRecords(session *session, request *request, record_list *records); + extern response *submitRequest(session *session, request *request); + + /* Response methods */ + extern bool isComplete(session *session, response *response); + extern request *getResponseRequest(session *session, response *response); + extern rejection_list *getResponseRejections(session *session, response *response); + extern record_list *getResponseRecords(session *session, response *response); + extern void setResponseRejections(session *session, response *response, rejection_list *rejections); + extern void setResponseRecords(session *session, response *response, record_list *records); + extern void setComplete(session *session, response *response, bool isComplete); + + /*Record Methods*/ + extern record_list *createRecordList(session *session); + extern void addRecord(session *session, record_list *record_list, record *record); + + extern record *getRecordCopy(session *session, record *record); + extern bool getRecordIsValid(session *session, record *record); + + extern string_list *getFieldIds(session *session, record *record); + extern field_list *getFields(session *session, record *record); + extern field *getField(session *session, record *record, const char *fieldId); + extern bool hasField(session *session, record *record, const char *fieldId); + + extern string_list *getConditionIds(session *session, record *record); + extern condition_list *getConditions(session *session, record *record); + extern condition *getCondition(session *session, record *record, const char *conditionId); + extern bool hasCondition(session *session, record *record, const char *conditionId); + + /*Rejection Methods*/ + extern rejection_list *createRejectionList(session *session); + extern void addRejection(session *session, rejection_list *rejection_list, rejection *rejection); + extern rejection *getRejectionCopy(session *session, rejection *rejection); + extern record *getRejectionRecord(session *session, rejection *rejection); + extern string_list *getRejectionReasons(session *session, rejection *rejection); + extern void addRejectionReason(session *session, rejection *rejection, const char *reason); + + /*Field Methods*/ + extern const char *getFieldId(session *session, field *field); + extern const char *getFieldType(session *session, field *field); + extern bool getFieldIsValid(session *session, field *field); + extern bool getFieldIsRequired(session *session, field *field); + extern bool getFieldIsNull(session *session, field *field); + + /* Field Value Retrieval */ + extern val *getFieldVal(session *session, field *field); + extern int getFieldIntVal(session *session, field *field); + extern long getFieldLongVal(session *session, field *field); + extern float getFieldFloatVal(session *session, field *field); + extern double getFieldDoubleVal(session *session, field *field); + extern signed char getFieldByteVal(session *session, field *field); + extern const char *getFieldStringVal(session *session, field *field); + extern bool getFieldBoolVal(session *session, field *field); + extern short getFieldShortVal(session *session, field *field); + extern val_list *getFieldListVal(session *session, field *field); + + /*Field Value Puts */ + extern void setFieldVal(session *session, field *field, val *value); + extern void setFieldIntVal(session *session, field *field, int value); + extern void setFieldLongVal(session *session, field *field, long value); + extern void setFieldFloatVal(session *session, field *field, float value); + extern void setFieldDoubleVal(session *session, field *field, double value); + extern void setFieldByteVal(session *session, field *field, signed char value); + extern void setFieldStringVal(session *session, field *field, const char *value); + extern void setFieldBoolVal(session *session, field *field, bool value); + extern void setFieldShortVal(session *session, field *field, short value); + extern void setFieldListVal(session *session, field *field, val_list *value); + + /*Condition Methods*/ + extern const char *getConditionId(session *session, condition *condition); + extern const char *getConditionType(session *session, condition *condition); + extern const char *getConditionOperator(session *session, condition *condition); + extern bool getConditionIsNull(session *session, condition *condition); + + /* Condition value retrieval */ + extern val *getConditionVal(session *session, condition *condition); + extern int getConditionIntVal(session *session, condition *condition); + extern long getConditionLongVal(session *session, condition *condition); + extern float getConditionFloatVal(session *session, condition *condition); + extern double getConditionDoubleVal(session *session, condition *condition); + extern signed char getConditionByteVal(session *session, condition *condition); + extern const char *getConditionStringVal(session *session, condition *condition); + extern bool getConditionBoolVal(session *session, condition *condition); + extern short getConditionShortVal(session *session, condition *condition); + extern val_list *getConditionListVal(session *session, condition *condition); + + /* Condition value puts */ + extern void setConditionVal(session *session, condition *condition, val *value); + extern void setConditionIntVal(session *session, condition *condition, int value); + extern void setConditionLongVal(session *session, condition *condition, long value); + extern void setConditionFloatVal(session *session, condition *condition, float value); + extern void setConditionDoubleVal(session *session, condition *condition, double value); + extern void setConditionByteVal(session *session, condition *condition, signed char value); + extern void setConditionStringVal(session *session, condition *condition, const char *value); + extern void setConditionBoolVal(session *session, condition *condition, bool value); + extern void setConditionShortVal(session *session, condition *condition, short value); + extern void setConditionListVal(session *session, condition *condition, val_list *value); + + /*List Utility Methods*/ + extern int getIntItem(session *session, val_list *list, int index); + extern long getLongItem(session *session, val_list *list, int index); + extern float getFloatItem(session *session, val_list *list, int index); + extern double getDoubleItem(session *session, val_list *list, int index); + extern signed char getByteItem(session *session, val_list *list, int index); + extern const char *getStringItem(session *session, val_list *list, int index); + extern bool getBoolItem(session *session, val_list *list, int index); + extern short getShortItem(session *session, val_list *list, int index); + extern list_item *getItem(session *session, val_list *list, int index); + extern val_list *getListItem(session *session, val_list *list, int index); + extern val_map *getMapItem(session *session, val_list *list, int index); + extern val_list *createList(session *session); + extern void addItem(session *session, val_list *list, list_item *item); + extern void addIntItem(session *session, val_list *list, int val); + extern void addLongItem(session *session, val_list *list, long val); + extern void addFloatItem(session *session, val_list *list, float val); + extern void addDoubleItem(session *session, val_list *list, double val); + extern void addByteItem(session *session, val_list *list, signed char val); + extern void addStringItem(session *session, val_list *list, const char *val); + extern void addBoolItem(session *session, val_list *list, bool val); + extern void addShortItem(session *session, val_list *list, short val); + extern void addListItem(session *session, val_list *list, val_list *val); + extern void addMapItem(session *session, val_list *list, val_map *map); + + /*Map Utility Methods*/ + extern val_map *createMap(session *session); + extern int getSize(session *session, val_map *map); + extern bool hasKey(session *session, val_map *map, const char *key); + + /*Map Value Retrieval Methods*/ + extern map_val *getVal(session *session, val_map *map, const char *key); + extern jobject getObjectVal(session *session, val_map *map, const char *key); + extern int getIntVal(session *session, val_map *map, const char *key); + extern long getLongVal(session *session, val_map *map, const char *key); + extern float getFloatVal(session *session, val_map *map, const char *key); + extern double getDoubleVal(session *session, val_map *map, const char *key); + extern signed char getByteVal(session *session, val_map *map, const char *key); + extern const char *getStringVal(session *session, val_map *map, const char *key); + extern bool getBoolVal(session *session, val_map *map, const char *key); + extern short getShortVal(session *session, val_map *map, const char *key); + extern val_list *getListVal(session *session, val_map *map, const char *key); + extern val_map *getMapVal(session *session, val_map *map, const char *key); + + /*Insert or Update Methods*/ + extern void putVal(session *session, val_map *map, const char *key, map_val *val); + extern void putObjectVal(session *session, val_map *map, const char *key, jobject val); + extern void putIntVal(session *session, val_map *map, const char *key, int val); + extern void putLongVal(session *session, val_map *map, const char *key, long val); + extern void putFloatVal(session *session, val_map *map, const char *key, float val); + extern void putDoubleVal(session *session, val_map *map, const char *key, double val); + extern void putByteVal(session *session, val_map *map, const char *key, signed char val); + extern void putStringVal(session *session, val_map *map, const char *key, const char *val); + extern void putBoolVal(session *session, val_map *map, const char *key, bool val); + extern void putShortVal(session *session, val_map *map, const char *key, short val); + extern void putListVal(session *session, val_map *map, const char *key, val_list *val); + extern void putMapVal(session *session, val_map *map, const char *key, val_map *val); + + /*Packet Methods*/ + extern void addPacketRecord(session *session, packet *packet, record *record); + extern void setPacketRecords(session *session, packet *packet, record_list *records); + extern void addPacketRecords(session *session, packet *packet, record_list *records); + extern void setPacketRejections(session *session, packet *packet, rejection_list *rejections); + extern void addPacketRejection(session *session, packet *packet, rejection *rejection); + extern void addPacketRejections(session *session, packet *packet, rejection_list *rejections); + extern record_list *getPacketRecords(session *session, packet *packet); + extern rejection_list *getPacketRejections(session *session, packet *packet); + +#ifdef __cplusplus +} +#endif diff --git a/src/cpp/main/libs/transformation/MessageApiTransformationLib.cpp b/src/cpp/main/libs/transformation/MessageApiTransformationLib.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3301ce0c589239314852adfe558a329ee5d778c4 --- /dev/null +++ b/src/cpp/main/libs/transformation/MessageApiTransformationLib.cpp @@ -0,0 +1,550 @@ +#include "MessageApiTransformationLib.h" +#include "MessageApiTransformation.h" +#include "gov_noaa_messageapi_transformations_NativeTransformation.h" + +/** + * Creates a C++ object and returns a pointer to it cast as a long. This allows the NativeTransformation method + * to hold onto it and manipulate it during the process method while preventing potential conflicts with + * other threads or transformations using the same native library. This is used inside the Java process method. + * The Native process method should be implemented in a separate User class wrapper. + */ +JNIEXPORT jlong JNICALL Java_gov_noaa_messageapi_transformations_NativeTransformation_create(JNIEnv* env, jobject transformation, jobject transformationMap) +{ + return reinterpret_cast(new MessageApiTransformation(env, transformation, transformationMap)); +} + +/** + * Deletes the C++ pointer (calls C++ destructor)) that references the object created during transformation construction. + * This call is made automatically by the Java process method after native processing has completed. + */ +JNIEXPORT void JNICALL Java_gov_noaa_messageapi_transformations_NativeTransformation_release(JNIEnv* env, jobject transformation, jlong transformationLib) +{ + delete reinterpret_cast(transformationLib); +} + +extern "C" +{ + + val_map *getConstructor(jlong message) + { + return reinterpret_cast(message)->getTransformationUtils()->getConstructor(); + } + + record_list *getRecords(jlong message, const char *key) + { + return reinterpret_cast(message)->getTransformationUtils()->getRecords(key); + } + + record_list *createRecordList(jlong message) + { + return reinterpret_cast(message)->getRecordUtils()->createRecordList(); + } + + void addRecord(jlong message, record_list *record_list, record *record) + { + return reinterpret_cast(message)->getRecordUtils()->addRecord(record_list, record); + } + + record *getRecord(jlong message, record_list *recordList, int recordIndex) + { + return reinterpret_cast(message)->getRecordUtils()->getRecord(recordList, recordIndex); + } + + record *getRecordCopy(jlong message, record *record) + { + return reinterpret_cast(message)->getRecordUtils()->getCopy(record); + } + + bool getRecordIsValid(jlong message, record *record) + { + return reinterpret_cast(message)->getRecordUtils()->isValid(record); + } + + string_list *getFieldIds(jlong message, record *record) + { + return reinterpret_cast(message)->getRecordUtils()->getFieldIds(record); + } + + field_list *getFields(jlong message, record *record) + { + return reinterpret_cast(message)->getRecordUtils()->getFields(record); + } + + field *getField(jlong message, record *record, const char* fieldId) + { + return reinterpret_cast(message)->getRecordUtils()->getField(record, fieldId); + } + + bool hasField(jlong message, record *record, const char *fieldId) + { + return reinterpret_cast(message)->getRecordUtils()->hasField(record, fieldId); + } + + string_list *getConditionIds(jlong message, record *record) + { + return reinterpret_cast(message)->getRecordUtils()->getConditionIds(record); + } + + condition_list *getConditions(jlong message, record *record) + { + return reinterpret_cast(message)->getRecordUtils()->getConditions(record); + } + + condition *getCondition(jlong message, record *record, const char *conditionId) + { + return reinterpret_cast(message)->getRecordUtils()->getCondition(record, conditionId); + } + + bool hasCondition(jlong message, record *record, const char *conditionId) + { + return reinterpret_cast(message)->getRecordUtils()->hasCondition(record, conditionId); + } + + /*Field Methods*/ + + const char *getFieldId(jlong message, field *field) + { + return reinterpret_cast(message)->getFieldUtils()->getId(field); + } + + const char *getFieldType(jlong message, field *field) + { + return reinterpret_cast(message)->getFieldUtils()->getType(field); + } + + bool getFieldIsValid(jlong message, field *field) + { + return reinterpret_cast(message)->getFieldUtils()->isValid(field); + } + + bool getFieldIsRequired(jlong message, field *field) + { + return reinterpret_cast(message)->getFieldUtils()->isRequired(field); + } + + bool getFieldIsNull(jlong message, field *field) + { + return reinterpret_cast(message)->getFieldUtils()->isNull(field); + } + + val *getFieldVal(jlong message, field *field) + { + return reinterpret_cast(message)->getFieldUtils()->getVal(field); + } + + int getFieldIntVal(jlong message, field *field) + { + return reinterpret_cast(message)->getFieldUtils()->getIntVal(field); + } + + long getFieldLongVal(jlong message, field *field) + { + return reinterpret_cast(message)->getFieldUtils()->getLongVal(field); + } + + float getFieldFloatVal(jlong message, field *field) + { + return reinterpret_cast(message)->getFieldUtils()->getFloatVal(field); + } + + double getFieldDoubleVal(jlong message, field *field) + { + return reinterpret_cast(message)->getFieldUtils()->getDoubleVal(field); + } + + signed char getFieldByteVal(jlong message, field *field) + { + return reinterpret_cast(message)->getFieldUtils()->getByteVal(field); + } + + const char *getFieldStringVal(jlong message, field *field) + { + return reinterpret_cast(message)->getFieldUtils()->getStringVal(field); + } + + bool getFieldBoolVal(jlong message, field *field) + { + return reinterpret_cast(message)->getFieldUtils()->getBoolVal(field); + } + + short getFieldShortVal(jlong message, field *field) + { + return reinterpret_cast(message)->getFieldUtils()->getShortVal(field); + } + + val_list *getFieldListVal(jlong message, field *field) + { + return reinterpret_cast(message)->getFieldUtils()->getListVal(field); + } + + val_map *getFieldMapVal(jlong message, field *field) + { + return reinterpret_cast(message)->getFieldUtils()->getMapVal(field); + } + + void setFieldVal(jlong message, field *field, val *value) + { + return reinterpret_cast(message)->getFieldUtils()->setVal(field, value); + } + + void setFieldIntVal(jlong message, field *field, int value) + { + return reinterpret_cast(message)->getFieldUtils()->setIntVal(field, value); + } + + void setFieldLongVal(jlong message, field *field, long value) + { + return reinterpret_cast(message)->getFieldUtils()->setLongVal(field, value); + } + + void setFieldFloatVal(jlong message, field *field, float value) + { + return reinterpret_cast(message)->getFieldUtils()->setFloatVal(field, value); + } + + void setFieldDoubleVal(jlong message, field *field, double value) + { + return reinterpret_cast(message)->getFieldUtils()->setDoubleVal(field, value); + } + + void setFieldByteVal(jlong message, field *field, signed char value) + { + return reinterpret_cast(message)->getFieldUtils()->setByteVal(field, value); + } + + void setFieldStringVal(jlong message, field *field, const char *value) + { + return reinterpret_cast(message)->getFieldUtils()->setStringVal(field, value); + } + + void setFieldBoolVal(jlong message, field *field, bool value) + { + return reinterpret_cast(message)->getFieldUtils()->setBoolVal(field, value); + } + + void setFieldShortVal(jlong message, field *field, short value) + { + return reinterpret_cast(message)->getFieldUtils()->setShortVal(field, value); + } + + void setFieldListVal(jlong message, field *field, val_list *value) + { + return reinterpret_cast(message)->getFieldUtils()->setListVal(field, value); + } + + void setFieldMapVal(jlong message, field *field, val_map *value) + { + return reinterpret_cast(message)->getFieldUtils()->setMapVal(field, value); + } + + /*Condition Methods*/ + + const char *getConditionId(jlong message, condition *condition) + { + return reinterpret_cast(message)->getConditionUtils()->getId(condition); + } + + const char *getConditionType(jlong message, condition *condition) + { + return reinterpret_cast(message)->getConditionUtils()->getType(condition); + } + + const char *getConditionOperator(jlong message, condition *condition) + { + return reinterpret_cast(message)->getConditionUtils()->getOperator(condition); + } + + bool getConditionIsNull(jlong message, condition *condition) + { + return reinterpret_cast(message)->getConditionUtils()->isNull(condition); + } + + val *getConditionVal(jlong message, condition *condition) + { + return reinterpret_cast(message)->getConditionUtils()->getVal(condition); + } + + int getConditionIntVal(jlong message, condition *condition) + { + return reinterpret_cast(message)->getConditionUtils()->getIntVal(condition); + } + + long getConditionLongVal(jlong message, condition *condition) + { + return reinterpret_cast(message)->getConditionUtils()->getLongVal(condition); + } + + float getConditionFloatVal(jlong message, condition *condition) + { + return reinterpret_cast(message)->getConditionUtils()->getFloatVal(condition); + } + + double getConditionDoubleVal(jlong message, condition *condition) + { + return reinterpret_cast(message)->getConditionUtils()->getDoubleVal(condition); + } + + signed char getConditionByteVal(jlong message, condition *condition) + { + return reinterpret_cast(message)->getConditionUtils()->getByteVal(condition); + } + + const char *getConditionStringVal(jlong message, condition *condition) + { + return reinterpret_cast(message)->getConditionUtils()->getStringVal(condition); + } + + bool getConditionBoolVal(jlong message, condition *condition) + { + return reinterpret_cast(message)->getConditionUtils()->getBoolVal(condition); + } + + short getConditionShortVal(jlong message, condition *condition) + { + return reinterpret_cast(message)->getConditionUtils()->getShortVal(condition); + } + + val_list *getConditionListVal(jlong message, condition *condition) + { + return reinterpret_cast(message)->getConditionUtils()->getListVal(condition); + } + + val_map *getConditionMapVal(jlong message, condition *condition) + { + return reinterpret_cast(message)->getConditionUtils()->getMapVal(condition); + } + + void setConditionVal(jlong message, condition *condition, val *value) + { + return reinterpret_cast(message)->getConditionUtils()->setVal(condition, value); + } + + void setConditionIntVal(jlong message, condition *condition, int value) + { + return reinterpret_cast(message)->getConditionUtils()->setIntVal(condition, value); + } + + void setConditionLongVal(jlong message, condition *condition, long value) + { + return reinterpret_cast(message)->getConditionUtils()->setLongVal(condition, value); + } + + void setConditionFloatVal(jlong message, condition *condition, float value) + { + return reinterpret_cast(message)->getConditionUtils()->setFloatVal(condition, value); + } + + void setConditionDoubleVal(jlong message, condition *condition, double value) + { + return reinterpret_cast(message)->getConditionUtils()->setDoubleVal(condition, value); + } + + void setConditionByteVal(jlong message, condition *condition, signed char value) + { + return reinterpret_cast(message)->getConditionUtils()->setByteVal(condition, value); + } + + void setConditionStringVal(jlong message, condition *condition, const char *value) + { + return reinterpret_cast(message)->getConditionUtils()->setStringVal(condition, value); + } + + void setConditionBoolVal(jlong message, condition *condition, bool value) + { + return reinterpret_cast(message)->getConditionUtils()->setBoolVal(condition, value); + } + + void setConditionShortVal(jlong message, condition *condition, short value) + { + return reinterpret_cast(message)->getConditionUtils()->setShortVal(condition, value); + } + + void setConditionListVal(jlong message, condition *condition, val_list *value) + { + return reinterpret_cast(message)->getConditionUtils()->setListVal(condition, value); + } + + void setConditionMapVal(jlong message, condition *condition, val_map *value) + { + return reinterpret_cast(message)->getConditionUtils()->setMapVal(condition, value); + } + + /*List Utility Methods*/ + + list_item *getItem(jlong message, val_list *list, int index) + { + return reinterpret_cast(message)->getListUtils()->getItem(list, index); + } + + val_list *getListItem(jlong message, val_list *list, int index) + { + return reinterpret_cast(message)->getListUtils()->getListItem(list, index); + } + + int getIntItem(jlong message, val_list *list, int index) + { + return reinterpret_cast(message)->getListUtils()->getIntItem(list, index); + } + + long getLongItem(jlong message, val_list *list, int index) + { + return reinterpret_cast(message)->getListUtils()->getLongItem(list, index); + } + + float getFloatItem(jlong message, val_list *list, int index) + { + return reinterpret_cast(message)->getListUtils()->getFloatItem(list, index); + } + + double getDoubleItem(jlong message, val_list *list, int index) + { + return reinterpret_cast(message)->getListUtils()->getDoubleItem(list, index); + } + + signed char getByteItem(jlong message, val_list *list, int index) + { + return reinterpret_cast(message)->getListUtils()->getByteItem(list, index); + } + + const char *getStringItem(jlong message, val_list *list, int index) + { + return reinterpret_cast(message)->getListUtils()->getStringItem(list, index); + } + + bool getBoolItem(jlong message, val_list *list, int index) + { + return reinterpret_cast(message)->getListUtils()->getBoolItem(list, index); + } + + short getShortItem(jlong message, val_list *list, int index) + { + return reinterpret_cast(message)->getListUtils()->getShortItem(list, index); + } + + val_list *createList(jlong message) + { + return reinterpret_cast(message)->getListUtils()->createList(); + } + + void addItem(jlong message, val_list *list, list_item *item) + { + return reinterpret_cast(message)->getListUtils()->addItem(list, item); + } + + void addIntItem(jlong message, val_list *list, int val) + { + return reinterpret_cast(message)->getListUtils()->addIntItem(list, val); + } + + void addLongItem(jlong message, val_list *list, long val) + { + return reinterpret_cast(message)->getListUtils()->addLongItem(list, val); + } + + void addFloatItem(jlong message, val_list *list, float val) + { + return reinterpret_cast(message)->getListUtils()->addFloatItem(list, val); + } + + void addDoubleItem(jlong message, val_list *list, double val) + { + return reinterpret_cast(message)->getListUtils()->addDoubleItem(list, val); + } + + void addByteItem(jlong message, val_list *list, signed char val) + { + return reinterpret_cast(message)->getListUtils()->addByteItem(list, val); + } + + void addStringItem(jlong message, val_list *list, const char *val) + { + return reinterpret_cast(message)->getListUtils()->addStringItem(list, val); + } + + void addBoolItem(jlong message, val_list *list, bool val) + { + return reinterpret_cast(message)->getListUtils()->addBoolItem(list, val); + } + + void addShortItem(jlong message, val_list *list, short val) + { + return reinterpret_cast(message)->getListUtils()->addShortItem(list, val); + } + + void addListItem(jlong message, val_list *list, val_list *val) + { + return reinterpret_cast(message)->getListUtils()->addListItem(list, val); + } + + /*Rejection Utils*/ + rejection_list *createRejectionList(jlong message) + { + return reinterpret_cast(message)->getRejectionUtils()->createRejectionList(); + } + + void addRejection(jlong message, rejection_list *rejection_list, rejection *rejection) + { + return reinterpret_cast(message)->getRejectionUtils()->addRejection(rejection_list, rejection); + } + + rejection *getRejectionCopy(jlong message, rejection *rejection) + { + return reinterpret_cast(message)->getRejectionUtils()->getCopy(rejection); + } + + record *getRejectionRecord(jlong message, rejection *rejection) + { + return reinterpret_cast(message)->getRejectionUtils()->getRecord(rejection); + } + + string_list *getRejectionReasons(jlong message, rejection *rejection) + { + return reinterpret_cast(message)->getRejectionUtils()->getReasons(rejection); + } + + void addRejectionReason(jlong message, rejection *rejection, const char *reason) + { + return reinterpret_cast(message)->getRejectionUtils()->addReason(rejection, reason); + } + + /*Packet Utils*/ + void addPacketRecord(jlong message, packet *packet, record *record) + { + return reinterpret_cast(message)->getPacketUtils()->addRecord(packet, record); + } + + void setPacketRecords(jlong message, packet *packet, record_list *records) + { + return reinterpret_cast(message)->getPacketUtils()->setRecords(packet, records); + } + + void addPacketRecords(jlong message, packet *packet, record_list *records) + { + return reinterpret_cast(message)->getPacketUtils()->addRecords(packet, records); + } + + void setPacketRejections(jlong message, packet *packet, rejection_list *rejections) + { + return reinterpret_cast(message)->getPacketUtils()->setRejections(packet, rejections); + } + + void addPacketRejection(jlong message, packet *packet, rejection *rejection) + { + return reinterpret_cast(message)->getPacketUtils()->addRejection(packet, rejection); + } + + void addPacketRejections(jlong message, packet *packet, rejection_list *rejections) + { + return reinterpret_cast(message)->getPacketUtils()->addRejections(packet, rejections); + } + + record_list *getPacketRecords(jlong message, packet *packet) + { + return reinterpret_cast(message)->getPacketUtils()->getRecords(packet); + } + + rejection_list *getPacketRejections(jlong message, packet *packet) + { + return reinterpret_cast(message)->getPacketUtils()->getRejections(packet); + } +} \ No newline at end of file diff --git a/src/cpp/main/libs/transformation/MessageApiTransformationLib.h b/src/cpp/main/libs/transformation/MessageApiTransformationLib.h new file mode 100644 index 0000000000000000000000000000000000000000..6c8a227530d1147e1cb66c95380812e89b40fe7d --- /dev/null +++ b/src/cpp/main/libs/transformation/MessageApiTransformationLib.h @@ -0,0 +1,176 @@ +#include +#include + +#include "messageapi_structs.h" + +/** + * @author Ryan Berkheimer + */ +#ifdef __cplusplus +extern "C" +{ +#endif + + /* Transformation methods */ + val_map *getConstructor(jlong message); + record_list *getRecords(jlong message, const char *key); + + /*Record Methods*/ + record_list *createRecordList(jlong message); + void addRecord(jlong message, record_list *record_list, record *record); + + record *getRecordCopy(jlong message, record *record); + bool getRecordIsValid(jlong message, record *record); + + string_list *getFieldIds(jlong message, record *record); + field_list *getFields(jlong message, record *record); + field *getField(jlong message, record *record, const char *fieldId); + bool hasField(jlong message, record *record, const char *fieldId); + + string_list *getConditionIds(jlong message, record *record); + condition_list *getConditions(jlong message, record *record); + condition *getCondition(jlong message, record *record, const char *conditionId); + bool hasCondition(jlong message, record *record, const char *conditionId); + + /*Rejection Methods*/ + rejection_list *createRejectionList(jlong message); + void addRejection(jlong message, rejection_list *rejection_list, rejection *rejection); + rejection *getRejectionCopy(jlong message, rejection *rejection); + record *getRejectionRecord(jlong message, rejection *rejection); + string_list *getRejectionReasons(jlong message, rejection *rejection); + void addRejectionReason(jlong message, rejection *rejection, const char *reason); + + /*Field Methods*/ + const char *getFieldId(jlong message, field *field); + const char *getFieldType(jlong message, field *field); + bool getFieldIsValid(jlong message, field *field); + bool getFieldIsRequired(jlong message, field *field); + bool getFieldIsNull(jlong message, field *field); + + val *getFieldVal(jlong message, field *field); + int getFieldIntVal(jlong message, field *field); + long getFieldLongVal(jlong message, field *field); + float getFieldFloatVal(jlong message, field *field); + double getFieldDoubleVal(jlong message, field *field); + signed char getFieldByteVal(jlong message, field *field); + const char *getFieldStringVal(jlong message, field *field); + bool getFieldBoolVal(jlong message, field *field); + short getFieldShortVal(jlong message, field *field); + val_list *getFieldListVal(jlong message, field *field); + val_map *getFieldMapVal(jlong message, field *field); + + void setFieldVal(jlong message, field *field, val *value); + void setFieldIntVal(jlong message, field *field, int value); + void setFieldLongVal(jlong message, field *field, long value); + void setFieldFloatVal(jlong message, field *field, float value); + void setFieldDoubleVal(jlong message, field *field, double value); + void setFieldByteVal(jlong message, field *field, signed char value); + void setFieldStringVal(jlong message, field *field, const char *value); + void setFieldBoolVal(jlong message, field *field, bool value); + void setFieldShortVal(jlong message, field *field, short value); + void setFieldListVal(jlong message, field *field, val_list *value); + void setFieldMapVal(jlong message, field *field, val_map *value); + + /*Condition Methods*/ + const char *getConditionId(jlong message, condition *condition); + const char *getConditionType(jlong message, condition *condition); + const char *getConditionOperator(jlong message, condition *condition); + bool getConditionIsNull(jlong message, condition *condition); + + val *getConditionVal(jlong message, condition *condition); + int getConditionIntVal(jlong message, condition *condition); + long getConditionLongVal(jlong message, condition *condition); + float getConditionFloatVal(jlong message, condition *condition); + double getConditionDoubleVal(jlong message, condition *condition); + signed char getConditionByteVal(jlong message, condition *condition); + const char *getConditionStringVal(jlong message, condition *condition); + bool getConditionBoolVal(jlong message, condition *condition); + short getConditionShortVal(jlong message, condition *condition); + val_list *getConditionListVal(jlong message, condition *condition); + val_map *getConditionMapVal(jlong message, condition *condition); + + void setConditionVal(jlong message, condition *condition, val *value); + void setConditionIntVal(jlong message, condition *condition, int value); + void setConditionLongVal(jlong message, condition *condition, long value); + void setConditionFloatVal(jlong message, condition *condition, float value); + void setConditionDoubleVal(jlong message, condition *condition, double value); + void setConditionByteVal(jlong message, condition *condition, signed char value); + void setConditionStringVal(jlong message, condition *condition, const char *value); + void setConditionBoolVal(jlong message, condition *condition, bool value); + void setConditionShortVal(jlong message, condition *condition, short value); + void setConditionListVal(jlong message, condition *condition, val_list *value); + void setConditionMapVal(jlong message, condition *condition, val_map *value); + + /*List Utility Methods*/ + val_list *createList(jlong message); + + int getIntItem(jlong message, val_list *list, int index); + long getLongItem(jlong message, val_list *list, int index); + float getFloatItem(jlong message, val_list *list, int index); + double getDoubleItem(jlong message, val_list *list, int index); + signed char getByteItem(jlong message, val_list *list, int index); + const char *getStringItem(jlong message, val_list *list, int index); + bool getBoolItem(jlong message, val_list *list, int index); + short getShortItem(jlong message, val_list *list, int index); + list_item *getItem(jlong message, val_list *list, int index); + val_list *getListItem(jlong message, val_list *list, int index); + val_map *getMapItem(jlong message, val_list *list, int index); + + void addItem(jlong message, val_list *list, list_item *item); + void addIntItem(jlong message, val_list *list, int val); + void addLongItem(jlong message, val_list *list, long val); + void addFloatItem(jlong message, val_list *list, float val); + void addDoubleItem(jlong message, val_list *list, double val); + void addByteItem(jlong message, val_list *list, signed char val); + void addStringItem(jlong message, val_list *list, const char *val); + void addBoolItem(jlong message, val_list *list, bool val); + void addShortItem(jlong message, val_list *list, short val); + void addListItem(jlong message, val_list *list, val_list *val); + void addMapItem(jlong message, val_list *list, val_map *map); + + /*Map Utility Methods*/ + val_map *createMap(jlong message); + int getSize(jlong message, val_map *map); + bool hasKey(jlong message, val_map *map, const char *key); + + /*Map Value Retrieval Methods*/ + map_val *getVal(jlong message, val_map *map, const char *key); + jobject getObjectVal(jlong message, val_map *map, const char *key); + int getIntVal(jlong message, val_map *map, const char *key); + long getLongVal(jlong message, val_map *map, const char *key); + float getFloatVal(jlong message, val_map *map, const char *key); + double getDoubleVal(jlong message, val_map *map, const char *key); + signed char getByteVal(jlong message, val_map *map, const char *key); + const char *getStringVal(jlong message, val_map *map, const char *key); + bool getBoolVal(jlong message, val_map *map, const char *key); + short getShortVal(jlong message, val_map *map, const char *key); + val_list *getListVal(jlong message, val_map *map, const char *key); + val_map *getMapVal(jlong message, val_map *map, const char *key); + + /*Insert or Update Methods*/ + void putVal(jlong message, val_map *map, const char *key, map_val *val); + void putObjectVal(jlong message, val_map *map, const char *key, jobject val); + void putIntVal(jlong message, val_map *map, const char *key, int val); + void putLongVal(jlong message, val_map *map, const char *key, long val); + void putFloatVal(jlong message, val_map *map, const char *key, float val); + void putDoubleVal(jlong message, val_map *map, const char *key, double val); + void putByteVal(jlong message, val_map *map, const char *key, signed char val); + void putStringVal(jlong message, val_map *map, const char *key, const char *val); + void putBoolVal(jlong message, val_map *map, const char *key, bool val); + void putShortVal(jlong message, val_map *map, const char *key, short val); + void putListVal(jlong message, val_map *map, const char *key, val_list *val); + void putMapVal(jlong message, val_map *map, const char *key, val_map *val); + + /*Packet Methods*/ + void addPacketRecord(jlong message, packet *packet, record *record); + void setPacketRecords(jlong message, packet *packet, record_list *records); + void addPacketRecords(jlong message, packet *packet, record_list *records); + void setPacketRejections(jlong message, packet *packet, rejection_list *rejections); + void addPacketRejection(jlong message, packet *packet, rejection *rejection); + void addPacketRejections(jlong message, packet *packet, rejection_list *rejections); + record_list *getPacketRecords(jlong message, packet *packet); + rejection_list *getPacketRejections(jlong message, packet *packet); + +#ifdef __cplusplus +} +#endif diff --git a/src/cpp/main/common/ConditionUtils.cpp b/src/cpp/main/utils/api/condition/ConditionUtils.cpp similarity index 93% rename from src/cpp/main/common/ConditionUtils.cpp rename to src/cpp/main/utils/api/condition/ConditionUtils.cpp index 9077a324867629f5f7a0db98b27d16dbb0fab9f5..821488b611b43e5f92782da7b13c7b0fba49a1f9 100644 --- a/src/cpp/main/common/ConditionUtils.cpp +++ b/src/cpp/main/utils/api/condition/ConditionUtils.cpp @@ -4,9 +4,9 @@ /* Default Constructor */ -ConditionUtils::ConditionUtils(JNIEnv *jvm, TypeUtils *typeUtils, ListUtils *listUtils) +ConditionUtils::ConditionUtils(JNIEnv *jvm, TypeUtils *typeUtils, ListUtils *listUtils, MapUtils *mapUtils) { - this->loadGlobalRefs(jvm, typeUtils, listUtils); + this->loadGlobalRefs(jvm, typeUtils, listUtils, mapUtils); this->loadMethodIds(); } @@ -134,6 +134,14 @@ struct val_list *ConditionUtils::getListVal(struct condition *condition) return valueList; } +struct val_map *ConditionUtils::getMapVal(struct condition *condition) +{ + struct val *value = this->getVal(condition); + struct val_map *valueMap = (struct val_map *)malloc(sizeof(struct val_map)); + valueMap->jmap = value->jvalue; + return valueMap; +} + void ConditionUtils::setVal(struct condition *condition, struct val *value) { this->jvm->CallVoidMethod(condition->jcondition, this->setValueMethodId, value->jvalue); @@ -200,12 +208,18 @@ void ConditionUtils::setListVal(struct condition *condition, struct val_list *va this->jvm->CallVoidMethod(condition->jcondition, this->setValueMethodId, value->jlist); } +void ConditionUtils::setMapVal(struct condition *condition, struct val_map *value) +{ + this->jvm->CallVoidMethod(condition->jcondition, this->setValueMethodId, value->jmap); +} + /* Private Methods */ -void ConditionUtils::loadGlobalRefs(JNIEnv *jvm, TypeUtils *typeUtils, ListUtils *listUtils) +void ConditionUtils::loadGlobalRefs(JNIEnv *jvm, TypeUtils *typeUtils, ListUtils *listUtils, MapUtils *mapUtils) { this->jvm = jvm; this->typeUtils = typeUtils; this->listUtils = listUtils; + this->mapUtils = mapUtils; } void ConditionUtils::loadMethodIds() diff --git a/src/cpp/main/common/ConditionUtils.h b/src/cpp/main/utils/api/condition/ConditionUtils.h similarity index 91% rename from src/cpp/main/common/ConditionUtils.h rename to src/cpp/main/utils/api/condition/ConditionUtils.h index fb6d3d439c321c0b9f99b9f728fa8f71429bca3f..d916e8a034aa3474fe02aef1f0d2131b1af35780 100644 --- a/src/cpp/main/common/ConditionUtils.h +++ b/src/cpp/main/utils/api/condition/ConditionUtils.h @@ -1,4 +1,3 @@ - #ifndef _CONDITIONUTILS_H #define _CONDITIONUTILS_H @@ -12,6 +11,7 @@ #include "JniUtils.h" #include "ListUtils.h" +#include "MapUtils.h" /** * This is the header for the ConditionUtils class. @@ -22,7 +22,7 @@ class ConditionUtils public: /*Default constructor/destructors*/ - ConditionUtils(JNIEnv *javaEnv, TypeUtils *typeUtils, ListUtils *listUtils); + ConditionUtils(JNIEnv *javaEnv, TypeUtils *typeUtils, ListUtils *listUtils, MapUtils *mapUtils); ~ConditionUtils(); /*API Methods*/ @@ -30,6 +30,7 @@ public: const char *getType(struct condition *condition); const char *getOperator(struct condition *condition); bool isNull(struct condition *condition); + struct val *getVal(struct condition *condition); int getIntVal(struct condition *condition); long getLongVal(struct condition *condition); @@ -40,6 +41,8 @@ public: bool getBoolVal(struct condition *condition); short getShortVal(struct condition *condition); struct val_list *getListVal(struct condition *condition); + struct val_map *getMapVal(struct condition *condition); + void setVal(struct condition *condition, struct val *value); void setIntVal(struct condition *condition, int value); void setLongVal(struct condition *condition, long value); @@ -50,12 +53,14 @@ public: void setBoolVal(struct condition *condition, bool value); void setShortVal(struct condition *condition, short value); void setListVal(struct condition *condition, struct val_list *value); + void setMapVal(struct condition *condition, struct val_map *value); private: /*Vars*/ JNIEnv *jvm; ListUtils *listUtils; TypeUtils *typeUtils; + MapUtils *mapUtils; /*Condition Methods*/ jmethodID getIdMethodId; @@ -66,7 +71,7 @@ private: /*Load method IDS for reuse. MethodIDS do not count against the jref count and do need to be released.*/ void loadMethodIds(); - void loadGlobalRefs(JNIEnv *env, TypeUtils *typeUtils, ListUtils *listUtils); + void loadGlobalRefs(JNIEnv *env, TypeUtils *typeUtils, ListUtils *listUtils, MapUtils *mapUtils); /*Grouped methods for returning the matching method signature string for a given interface*/ const char *getMethodSignature(const char *methodName); diff --git a/src/cpp/main/common/EndpointUtils.cpp b/src/cpp/main/utils/api/endpoint/EndpointUtils.cpp similarity index 89% rename from src/cpp/main/common/EndpointUtils.cpp rename to src/cpp/main/utils/api/endpoint/EndpointUtils.cpp index 924366a066feeceffc3c73d391ed9557bc0e5e29..f408197fbb265eaa5d2a91879e2cd30144947dbb 100644 --- a/src/cpp/main/common/EndpointUtils.cpp +++ b/src/cpp/main/utils/api/endpoint/EndpointUtils.cpp @@ -52,6 +52,14 @@ struct field_list *EndpointUtils::getDefaultFields() return field_list; } +struct val_map *EndpointUtils::getConstructor() +{ + jobject jMap = this->jvm->CallObjectMethod(this->endpoint, this->getConstructorMethodId); + struct val_map *map = (struct val_map *)malloc(sizeof(struct val_map)); + map->jmap = jMap; + return map; +} + struct packet *EndpointUtils::createPacket() { jobject jpacket = this->jvm->CallObjectMethod(this->endpoint, this->createPacketMethodId); @@ -93,6 +101,7 @@ void EndpointUtils::loadMethodIds() jclass endpointClass = JniUtils::getObjectClass(this->jvm, this->endpoint); this->getStateContainerMethodId = JniUtils::getMethod(this->jvm, endpointClass, "getStateContainer", this->getMethodSignature("getStateContainer"), false); this->getDefaultFieldsMethodId = JniUtils::getMethod(this->jvm, endpointClass, "getDefaultFields", this->getMethodSignature("getDefaultFields"), false); + this->getConstructorMethodId = JniUtils::getMethod(this->jvm, endpointClass, "getConstructor", this->getMethodSignature("getConstructor"), false); this->createPacketMethodId = JniUtils::getMethod(this->jvm, endpointClass, "createPacket", this->getMethodSignature("createPacket"), false); this->createRecordMethodId = JniUtils::getMethod(this->jvm, endpointClass, "createRecord", this->getMethodSignature("createRecord"), false); this->createRejectionMethodId = JniUtils::getMethod(this->jvm, endpointClass, "createRejection", this->getMethodSignature("createRejection"), false); @@ -109,6 +118,10 @@ const char *EndpointUtils::getMethodSignature(const char *methodName) { return "()Ljava/util/List;"; } + else if (strcmp(methodName, "getConstructor") == 0) + { + return "()Ljava/util/Map;"; + } else if (strcmp(methodName, "createPacket") == 0) { return "()Lgov/noaa/messageapi/interfaces/IPacket;"; diff --git a/src/cpp/main/common/EndpointUtils.h b/src/cpp/main/utils/api/endpoint/EndpointUtils.h similarity index 96% rename from src/cpp/main/common/EndpointUtils.h rename to src/cpp/main/utils/api/endpoint/EndpointUtils.h index 484fbb08c4f1003365183c8c7fff3f661a56597c..4b09f23dc9d4ffa448f0fedbda620bf5e832b1e1 100644 --- a/src/cpp/main/common/EndpointUtils.h +++ b/src/cpp/main/utils/api/endpoint/EndpointUtils.h @@ -1,4 +1,3 @@ - #ifndef _ENDPOINTUTILS_H #define _ENDPOINTUTILS_H @@ -37,6 +36,7 @@ public: /*Endpoint Methods*/ struct record *getStateContainer(); struct field_list *getDefaultFields(); + struct val_map *getConstructor(); struct packet *createPacket(); struct record *createRecord(); struct rejection *createRejection(struct record *record, const char *reason); @@ -51,6 +51,7 @@ private: /*Endpoint Methods*/ jmethodID getStateContainerMethodId; jmethodID getDefaultFieldsMethodId; + jmethodID getConstructorMethodId; jmethodID createPacketMethodId; jmethodID createRecordMethodId; jmethodID createRejectionMethodId; diff --git a/src/cpp/main/common/FieldUtils.cpp b/src/cpp/main/utils/api/field/FieldUtils.cpp similarity index 92% rename from src/cpp/main/common/FieldUtils.cpp rename to src/cpp/main/utils/api/field/FieldUtils.cpp index 9bf2083d7c9520c87f99c272b475ede3f4f36f90..76a59e60c2132ccbc92198214e819eb32c9631f3 100644 --- a/src/cpp/main/common/FieldUtils.cpp +++ b/src/cpp/main/utils/api/field/FieldUtils.cpp @@ -4,9 +4,9 @@ /** Constructor */ -FieldUtils::FieldUtils(JNIEnv *jvm, TypeUtils *typeUtils, ListUtils *listUtils) +FieldUtils::FieldUtils(JNIEnv *jvm, TypeUtils *typeUtils, ListUtils *listUtils, MapUtils *mapUtils) { - this->loadGlobalRefs(jvm, typeUtils, listUtils); + this->loadGlobalRefs(jvm, typeUtils, listUtils, mapUtils); this->loadMethodIds(); } @@ -138,6 +138,14 @@ struct val_list *FieldUtils::getListVal(struct field *field) return valueList; } +struct val_map *FieldUtils::getMapVal(struct field *field) +{ + struct val *value = this->getVal(field); + struct val_map *valueMap = (struct val_map *)malloc(sizeof(struct val_map)); + valueMap->jmap = value->jvalue; + return valueMap; +} + void FieldUtils::setVal(struct field *field, struct val *value) { this->jvm->CallVoidMethod(field->jfield, this->setValueMethodId, value->jvalue); @@ -182,7 +190,7 @@ void FieldUtils::setStringVal(struct field *field, const char *value) { jstring jStringVal = this->typeUtils->toJavaString(value); this->jvm->CallVoidMethod(field->jfield, this->setValueMethodId, jStringVal); - this->jvm->DeleteLocalRef(jStringVal); + //this->jvm->DeleteLocalRef(jStringVal); } void FieldUtils::setBoolVal(struct field *field, bool value) @@ -204,12 +212,18 @@ void FieldUtils::setListVal(struct field *field, struct val_list *value) this->jvm->CallVoidMethod(field->jfield, this->setValueMethodId, value->jlist); } +void FieldUtils::setMapVal(struct field *field, struct val_map *value) +{ + this->jvm->CallVoidMethod(field->jfield, this->setValueMethodId, value->jmap); +} + /* Private Methods */ -void FieldUtils::loadGlobalRefs(JNIEnv *jvm, TypeUtils *typeUtils, ListUtils *listUtils) +void FieldUtils::loadGlobalRefs(JNIEnv *jvm, TypeUtils *typeUtils, ListUtils *listUtils, MapUtils *mapUtils) { this->jvm = jvm; this->typeUtils = typeUtils; this->listUtils = listUtils; + this->mapUtils = mapUtils; } void FieldUtils::loadMethodIds() @@ -240,11 +254,11 @@ const char *FieldUtils::getMethodSignature(const char *methodName) } else if (strcmp(methodName, "isValid") == 0) { - return "()Z"; + return "()Ljava/lang/Boolean;"; } else if (strcmp(methodName, "isRequired") == 0) { - return "()Z"; + return "()Ljava/lang/Boolean;"; } else if (strcmp(methodName, "setValue") == 0) { diff --git a/src/cpp/main/common/FieldUtils.h b/src/cpp/main/utils/api/field/FieldUtils.h similarity index 91% rename from src/cpp/main/common/FieldUtils.h rename to src/cpp/main/utils/api/field/FieldUtils.h index 22574e178d3011ce33ab436a0f5aa5fcc6ed044f..34a8ff677173808cc208af99816c031fb025a472 100644 --- a/src/cpp/main/common/FieldUtils.h +++ b/src/cpp/main/utils/api/field/FieldUtils.h @@ -1,4 +1,3 @@ - #ifndef _FIELDUTILS_H #define _FIELDUTILS_H @@ -13,6 +12,7 @@ #include "JniUtils.h" #include "TypeUtils.h" #include "ListUtils.h" +#include "MapUtils.h" /** * This is the header for the FieldUtils class. @@ -23,7 +23,7 @@ class FieldUtils public: /*Default constructor/destructors*/ - FieldUtils(JNIEnv *javaEnv, TypeUtils *typeUtils, ListUtils *listUtils); + FieldUtils(JNIEnv *javaEnv, TypeUtils *typeUtils, ListUtils *listUtils, MapUtils *mapUtils); ~FieldUtils(); /*Field Methods*/ @@ -32,6 +32,7 @@ public: bool isValid(struct field *field); bool isRequired(struct field *field); bool isNull(struct field *field); + struct val *getVal(struct field *field); int getIntVal(struct field *field); long getLongVal(struct field *field); @@ -42,6 +43,8 @@ public: bool getBoolVal(struct field *field); short getShortVal(struct field *field); struct val_list *getListVal(struct field *field); + struct val_map *getMapVal(struct field *field); + void setVal(struct field *field, struct val *value); void setIntVal(struct field *field, int value); void setLongVal(struct field *field, long value); @@ -52,6 +55,7 @@ public: void setBoolVal(struct field *field, bool value); void setShortVal(struct field *field, short value); void setListVal(struct field *field, struct val_list *value); + void setMapVal(struct field *field, struct val_map *value); private: @@ -59,6 +63,7 @@ private: JNIEnv *jvm; TypeUtils *typeUtils; ListUtils *listUtils; + MapUtils *mapUtils; /*Field Methods*/ jmethodID getIdMethodId; @@ -70,7 +75,7 @@ private: /*Load method IDS for reuse. MethodIDS do not count against the jref count and do need to be released.*/ void loadMethodIds(); - void loadGlobalRefs(JNIEnv *env, TypeUtils *typeUtils, ListUtils *listUtils); + void loadGlobalRefs(JNIEnv *env, TypeUtils *typeUtils, ListUtils *listUtils, MapUtils *mapUtils); /*Grouped methods for returning the matching method signature string for a given interface*/ const char *getMethodSignature(const char *methodName); diff --git a/src/cpp/main/common/PacketUtils.cpp b/src/cpp/main/utils/api/packet/PacketUtils.cpp similarity index 100% rename from src/cpp/main/common/PacketUtils.cpp rename to src/cpp/main/utils/api/packet/PacketUtils.cpp diff --git a/src/cpp/main/common/PacketUtils.h b/src/cpp/main/utils/api/packet/PacketUtils.h similarity index 99% rename from src/cpp/main/common/PacketUtils.h rename to src/cpp/main/utils/api/packet/PacketUtils.h index ea1033a85c928df8da9db03cef100259a90a44fe..0c745ded23da0fc61c7f00b4f939d314de8e2938 100644 --- a/src/cpp/main/common/PacketUtils.h +++ b/src/cpp/main/utils/api/packet/PacketUtils.h @@ -1,4 +1,3 @@ - #ifndef _PACKETUTILS_H #define _PACKETUTILS_H diff --git a/src/cpp/main/common/ProtocolRecordUtils.cpp b/src/cpp/main/utils/api/records/protocol/ProtocolRecordUtils.cpp similarity index 100% rename from src/cpp/main/common/ProtocolRecordUtils.cpp rename to src/cpp/main/utils/api/records/protocol/ProtocolRecordUtils.cpp diff --git a/src/cpp/main/common/ProtocolRecordUtils.h b/src/cpp/main/utils/api/records/protocol/ProtocolRecordUtils.h similarity index 99% rename from src/cpp/main/common/ProtocolRecordUtils.h rename to src/cpp/main/utils/api/records/protocol/ProtocolRecordUtils.h index 9c5e52392137ed52a5647626d4367dc780b20f03..c89610817eb9e999fbf7d66285b28f527f40e1d7 100644 --- a/src/cpp/main/common/ProtocolRecordUtils.h +++ b/src/cpp/main/utils/api/records/protocol/ProtocolRecordUtils.h @@ -1,4 +1,3 @@ - #ifndef _PROTOCOLRECORDUTILS_H #define _PROTOCOLRECORDUTILS_H diff --git a/src/cpp/main/common/RecordUtils.cpp b/src/cpp/main/utils/api/records/schema/RecordUtils.cpp similarity index 94% rename from src/cpp/main/common/RecordUtils.cpp rename to src/cpp/main/utils/api/records/schema/RecordUtils.cpp index 4388d033c7bbac790e5cf6f33ea707ed0b050cf3..86ca84080b46e534c6174f9902f3641201d85742 100644 --- a/src/cpp/main/common/RecordUtils.cpp +++ b/src/cpp/main/utils/api/records/schema/RecordUtils.cpp @@ -29,6 +29,13 @@ bool RecordUtils::isValid(struct record *record) return (bool)this->jvm->CallBooleanMethod(record->jrecord, this->isValidMethodId); } +void RecordUtils::setValid(struct record *record, bool isValid) +{ + jobject jBoolVal = jvm->NewObject(this->typeUtils->getBoolClass(), this->typeUtils->createBoolMethod(), (jboolean)isValid); + this->jvm->CallVoidMethod(record->jrecord, this->setValidMethodId, jBoolVal); + this->jvm->DeleteLocalRef(jBoolVal); +} + struct record *RecordUtils::getCopy(struct record *record) { jobject jRecordCopy = this->jvm->CallObjectMethod(record->jrecord, this->getCopyMethodId); @@ -166,6 +173,7 @@ void RecordUtils::loadMethodIds() jclass recordClass = JniUtils::getNamedClass(this->jvm, "gov/noaa/messageapi/interfaces/IRecord"); /*Intrinsic Methods*/ this->isValidMethodId = JniUtils::getMethod(this->jvm, recordClass, "isValid", this->getMethodSignature("isValid"), false); + this->setValidMethodId = JniUtils::getMethod(this->jvm, recordClass, "setValid", this->getMethodSignature("setValid"), false); this->getCopyMethodId = JniUtils::getMethod(this->jvm, recordClass, "getCopy", this->getMethodSignature("getCopy"), false); /*Field Related Methods*/ this->getFieldIdsMethodId = JniUtils::getMethod(this->jvm, recordClass, "getFieldIds", this->getMethodSignature("getFieldIds"), false); @@ -186,6 +194,11 @@ const char *RecordUtils::getMethodSignature(const char *methodName) { return "()Ljava/lang/Boolean;"; } + else if (strcmp(methodName, "setValid") == 0) + { + return "(Ljava/lang/Boolean;)V"; + } + else if (strcmp(methodName, "getCopy") == 0) { return "()Lgov/noaa/messageapi/interfaces/IRecord;"; diff --git a/src/cpp/main/common/RecordUtils.h b/src/cpp/main/utils/api/records/schema/RecordUtils.h similarity index 96% rename from src/cpp/main/common/RecordUtils.h rename to src/cpp/main/utils/api/records/schema/RecordUtils.h index 56d2a406ae9fcd8d6162d06ca81722727d9c4e04..c1002d5daf55a1781435b76402b2b0e2578e4f5b 100644 --- a/src/cpp/main/common/RecordUtils.h +++ b/src/cpp/main/utils/api/records/schema/RecordUtils.h @@ -1,4 +1,3 @@ - #ifndef _RECORDUTILS_H #define _RECORDUTILS_H @@ -35,6 +34,7 @@ public: struct record *getCopy(struct record *record); bool isValid(struct record *record); + void setValid(struct record *record, bool isValid); bool hasField(struct record *record, const char *fieldId); struct string_list *getFieldIds(struct record *record); @@ -54,6 +54,7 @@ private: /*Record Methods*/ jmethodID isValidMethodId; + jmethodID setValidMethodId; jmethodID getCopyMethodId; jmethodID getFieldIdsMethodId; jmethodID getFieldsMethodId; diff --git a/src/cpp/main/common/RejectionUtils.cpp b/src/cpp/main/utils/api/rejection/RejectionUtils.cpp similarity index 100% rename from src/cpp/main/common/RejectionUtils.cpp rename to src/cpp/main/utils/api/rejection/RejectionUtils.cpp diff --git a/src/cpp/main/common/RejectionUtils.h b/src/cpp/main/utils/api/rejection/RejectionUtils.h similarity index 99% rename from src/cpp/main/common/RejectionUtils.h rename to src/cpp/main/utils/api/rejection/RejectionUtils.h index 1f8c07287f19a5e15a7bed7e47363a52585b2b88..da8d3c69f33f01ca6611bbf01e30c6bd6558ab3d 100644 --- a/src/cpp/main/common/RejectionUtils.h +++ b/src/cpp/main/utils/api/rejection/RejectionUtils.h @@ -1,4 +1,3 @@ - #ifndef _REJECTIONUTILS_H #define _REJECTIONUTILS_H diff --git a/src/cpp/main/common/RequestUtils.cpp b/src/cpp/main/utils/api/request/RequestUtils.cpp similarity index 95% rename from src/cpp/main/common/RequestUtils.cpp rename to src/cpp/main/utils/api/request/RequestUtils.cpp index a919644e48f140bdb41647190b648e8de4218b06..70f0ab9e7c36dea1eb77abc0df7a68904103f718 100644 --- a/src/cpp/main/common/RequestUtils.cpp +++ b/src/cpp/main/utils/api/request/RequestUtils.cpp @@ -58,17 +58,17 @@ struct record *RequestUtils::createRecord(struct request *request) struct request *RequestUtils::getCopy(struct request *request) { jobject jrequest = this->jvm->CallObjectMethod(request->jrequest, this->getCopyDefaultMethodId); - struct request *request = (struct request *)malloc(sizeof(struct request) + sizeof(jrequest)); - request->jrequest = jrequest; - return request; + struct request *requestCopy = (struct request *)malloc(sizeof(struct request) + sizeof(jrequest)); + requestCopy->jrequest = jrequest; + return requestCopy; } struct request *RequestUtils::getCopy(struct request *request, struct val_list *copy_components) { jobject jrequest = this->jvm->CallObjectMethod(request->jrequest, this->getCopyDefaultMethodId, copy_components->jlist); - struct request *request = (struct request *)malloc(sizeof(struct request) + sizeof(jrequest)); - request->jrequest = jrequest; - return request; + struct request *requestCopy = (struct request *)malloc(sizeof(struct request) + sizeof(jrequest)); + requestCopy->jrequest = jrequest; + return requestCopy; } const char *RequestUtils::getType(struct request *request) diff --git a/src/cpp/main/common/RequestUtils.h b/src/cpp/main/utils/api/request/RequestUtils.h similarity index 99% rename from src/cpp/main/common/RequestUtils.h rename to src/cpp/main/utils/api/request/RequestUtils.h index 843f737ae0d6cd2f71bf5829bf2055842d8aa10a..b7347c46d7297c28d12be5e498c6572e5e8b6357 100644 --- a/src/cpp/main/common/RequestUtils.h +++ b/src/cpp/main/utils/api/request/RequestUtils.h @@ -1,4 +1,3 @@ - #ifndef _REQUESTUTILS_H #define _REQUESTUTILS_H diff --git a/src/cpp/main/utils/api/response/ResponseUtils.cpp b/src/cpp/main/utils/api/response/ResponseUtils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ab03676680ea08857c35eabcab7e46e7e5da01d3 --- /dev/null +++ b/src/cpp/main/utils/api/response/ResponseUtils.cpp @@ -0,0 +1,146 @@ +#include "ResponseUtils.h" + +#include + +/** + * Responses are returned by calling submit on a request. Responses operate asynchronously, + * setting an isComplete flag from false to true whenever the specified process is complete. + * Responses execute the request, and holds any records and/or rejections + * that are returned by the evaluation of the request. These records are an aggregate of all + * computation paths through a given request, so may contain records gathered from multiple sources + * in the same computation. + * + * @author Ryan Berkheimer + */ + +/* Default Constructor */ +ResponseUtils::ResponseUtils(JNIEnv *jvm, TypeUtils *typeUtils, ListUtils *listUtils) +{ + this->loadGlobalRefs(jvm, typeUtils, listUtils); + this->loadMethodIds(); +} + +/* Default Destructor */ +ResponseUtils::~ResponseUtils() +{ + try + {} + catch (const std::exception &e) + { + std::cout << e.what(); + } +} + +/* Public API */ + +bool ResponseUtils::isComplete(struct response *response) +{ + jboolean jBoolVal = this->jvm->CallBooleanMethod(response->jresponse, this->isCompleteMethodId); + bool boolVal = (bool)(jBoolVal != JNI_FALSE); + return boolVal; +} + +struct request *ResponseUtils::getRequest(struct response *response) +{ + jobject jrequest = this->jvm->CallObjectMethod(response->jresponse, this->getRequestMethodId); + struct request *request = (struct request *)malloc(sizeof(struct request) + sizeof(jrequest)); + request->jrequest = jrequest; + return request; +} + +struct rejection_list *ResponseUtils::getRejections(struct response *response) +{ + jobject jRejections = this->jvm->CallObjectMethod(response->jresponse, this->getRejectionsMethodId); + int rejectionCount = this->listUtils->getListLength(jRejections); + struct rejection_list *rejection_list = (struct rejection_list *)malloc(sizeof(struct rejection_list)); + rejection_list->count = rejectionCount; + rejection_list->jrejections = jRejections; + + return rejection_list; +} + +struct record_list *ResponseUtils::getRecords(struct response *response) +{ + jobject jRecords = this->jvm->CallObjectMethod(response->jresponse, this->getRecordsMethodId); + int recordCount = this->listUtils->getListLength(jRecords); + struct record_list *record_list = (struct record_list *)malloc(sizeof(struct record_list)); + record_list->count = recordCount; + record_list->jrecords = jRecords; + + return record_list; +} + +void ResponseUtils::setRejections(struct response *response, struct rejection_list *rejections) +{ + this->jvm->CallVoidMethod(response->jresponse, this->setRejectionsMethodId, rejections->jrejections); +} + +void ResponseUtils::setRecords(struct response *response, struct record_list *records) +{ + this->jvm->CallVoidMethod(response->jresponse, this->setRecordsMethodId, records->jrecords); +} + +void ResponseUtils::setComplete(struct response *response, bool isComplete) +{ + jobject jBoolVal = jvm->NewObject(this->typeUtils->getBoolClass(), this->typeUtils->createBoolMethod(), (jboolean)isComplete); + this->jvm->CallVoidMethod(response->jresponse, this->setCompleteMethodId, jBoolVal); + this->jvm->DeleteLocalRef(jBoolVal); +} + +/* Private Methods */ + +void ResponseUtils::loadGlobalRefs(JNIEnv *jvm, TypeUtils *typeUtils, ListUtils *listUtils) +{ + this->jvm = jvm; + this->typeUtils = typeUtils; + this->listUtils = listUtils; +} + +void ResponseUtils::loadMethodIds() +{ + jclass responseClass = JniUtils::getNamedClass(this->jvm, "gov/noaa/messageapi/interfaces/IResponse"); + + this->isCompleteMethodId = JniUtils::getMethod(this->jvm, responseClass, "isComplete", this->getMethodSignature("isComplete"), false); + this->getRequestMethodId = JniUtils::getMethod(this->jvm, responseClass, "getRequest", this->getMethodSignature("getRequest"), false); + this->getRejectionsMethodId = JniUtils::getMethod(this->jvm, responseClass, "getRejections", this->getMethodSignature("getRejections"), false); + this->getRecordsMethodId = JniUtils::getMethod(this->jvm, responseClass, "getRecords", this->getMethodSignature("getRecords"), false); + this->setRejectionsMethodId = JniUtils::getMethod(this->jvm, responseClass, "setRejections", this->getMethodSignature("setRejections"), false); + this->setRecordsMethodId = JniUtils::getMethod(this->jvm, responseClass, "setRecords", this->getMethodSignature("setRecords"), false); + this->setCompleteMethodId = JniUtils::getMethod(this->jvm, responseClass, "setComplete", this->getMethodSignature("setComplete"), false); + + jvm->DeleteLocalRef(responseClass); +} + + +const char *ResponseUtils::getMethodSignature(const char *methodName) +{ + if (strcmp(methodName, "isComplete") == 0) + { + return "()Z"; + } + else if (strcmp(methodName, "getRequest") == 0) + { + return "()Lgov/noaa/messageapi/interfaces/IRequest;"; + } + else if (strcmp(methodName, "getRejections") == 0) + { + return "()Ljava/util/List;"; + } + else if (strcmp(methodName, "getRecords") == 0) + { + return "()Ljava/util/List;"; + } + else if (strcmp(methodName, "setRejections") == 0) + { + return "(Ljava/util/List;)V"; + } + else if (strcmp(methodName, "setRecords") == 0) + { + return "(Ljava/util/List;)V"; + } + else if (strcmp(methodName, "setComplete") == 0) + { + return "(Z)V"; + } + return NULL; +} \ No newline at end of file diff --git a/src/cpp/main/utils/api/response/ResponseUtils.h b/src/cpp/main/utils/api/response/ResponseUtils.h new file mode 100644 index 0000000000000000000000000000000000000000..d08e7bd40bc9f938884b8938a728dd0374d7afc2 --- /dev/null +++ b/src/cpp/main/utils/api/response/ResponseUtils.h @@ -0,0 +1,74 @@ +#ifndef _RESPONSEUTILS_H +#define _RESPONSEUTILS_H + +#include +#include +#include "messageapi_structs.h" + +#ifdef __cplusplus +#include +#include +#include "ListUtils.h" +#include "TypeUtils.h" + +/** + * Responses are returned by calling submit on a request. Responses operate asynchronously, + * setting an isComplete flag from false to true whenever the specified process is complete. + * Responses execute the request, and holds records and/or rejections + * that are returned by the evaluation of the request. These records are an aggregate of all + * computation paths through a given request, so may contain records gathered from multiple sources + * in the same computation. + * + * @author Ryan Berkheimer + */ +class ResponseUtils +{ + +public: + /*Default constructor/destructors*/ + ResponseUtils(JNIEnv *javaEnv, TypeUtils *typeUtils, ListUtils *listUtils); + ~ResponseUtils(); + + /* Response Methods */ + bool isComplete(struct response *response); + struct request *getRequest(struct response *response); + struct rejection_list *getRejections(struct response *response); + struct record_list *getRecords(struct response *response); + void setRejections(struct response *response, struct rejection_list *rejections); + void setRecords(struct response *response, struct record_list *records); + void setComplete(struct response *response, bool isComplete); + +private: + /*Vars*/ + JNIEnv *jvm; + ListUtils *listUtils; + TypeUtils *typeUtils; + + /*Request Methods*/ + jmethodID isCompleteMethodId; + jmethodID getRequestMethodId; + jmethodID getRejectionsMethodId; + jmethodID getRecordsMethodId; + jmethodID setRejectionsMethodId; + jmethodID setRecordsMethodId; + jmethodID setCompleteMethodId; + + + /*Load method IDS for reuse. MethodIDS do not count against the jref count and do need to be released.*/ + void loadMethodIds(); + void loadGlobalRefs(JNIEnv *env, TypeUtils *typeUtils, ListUtils *listUtils); + + /*Grouped methods for returning the matching method signature string for a given interface*/ + const char *getMethodSignature(const char *methodName); +}; + +extern "C" +{ + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/cpp/main/utils/api/session/SessionUtils.cpp b/src/cpp/main/utils/api/session/SessionUtils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..01b802adaa0d868dff18847b5177093b545dd018 --- /dev/null +++ b/src/cpp/main/utils/api/session/SessionUtils.cpp @@ -0,0 +1,66 @@ +#include "SessionUtils.h" + +#include + +/** + * Sessions are the top level API container of any given computation. Sessions + * bootstrap from a specification map and 'lock-in' a computation environment, + * allowing requests to be created. + * + * @author Ryan Berkheimer + */ + +/* Default Constructor */ +SessionUtils::SessionUtils(JNIEnv *jvm, jobject session) +{ + this->loadGlobalRefs(jvm, session); + this->loadMethodIds(); +} + +/* Default Destructor */ +SessionUtils::~SessionUtils() +{ + try + {} + catch (const std::exception &e) + { + std::cout << e.what(); + } +} + +/* Public API */ + +struct request *SessionUtils::createRequest() +{ + jobject jrequest = this->jvm->CallObjectMethod(this->session, this->createRequestMethodId); + struct request *request = (struct request *)malloc(sizeof(struct request) + sizeof(jrequest)); + request->jrequest = jrequest; + return request; +} + +/* Private Methods */ + +void SessionUtils::loadGlobalRefs(JNIEnv *jvm, jobject session) +{ + this->jvm = jvm; + this->session = session; +} + +void SessionUtils::loadMethodIds() +{ + jclass sessionClass = JniUtils::getNamedClass(this->jvm, "gov/noaa/messageapi/interfaces/ISession"); + + this->createRequestMethodId = JniUtils::getMethod(this->jvm, sessionClass, "createRequest", this->getMethodSignature("createRequest"), false); + + jvm->DeleteLocalRef(sessionClass); +} + + +const char *SessionUtils::getMethodSignature(const char *methodName) +{ + if (strcmp(methodName, "createRequest") == 0) + { + return "()Lgov/noaa/messageapi/interfaces/IRequest;"; + } + return NULL; +} \ No newline at end of file diff --git a/src/cpp/main/utils/api/session/SessionUtils.h b/src/cpp/main/utils/api/session/SessionUtils.h new file mode 100644 index 0000000000000000000000000000000000000000..00b834a113dbc9277909f89e5908bb208c2e0fec --- /dev/null +++ b/src/cpp/main/utils/api/session/SessionUtils.h @@ -0,0 +1,60 @@ +#ifndef _SESSIONUTILS_H +#define _SESSIONUTILS_H + +#include +#include +#include "messageapi_structs.h" + +#ifdef __cplusplus +#include +#include + +#include "JniUtils.h" + +/** + * Sessions are the top level API container of any given computation. Sessions + * bootstrap from a specification map and 'lock-in' a computation environment, + * allowing requests to be created. + * + * @author Ryan Berkheimer + */ +class SessionUtils +{ + +public: + /*Default constructor */ + SessionUtils(JNIEnv *javaEnv, jobject jSession); + + /*Default Destructor */ + ~SessionUtils(); + + /* Session Methods */ + struct request *createRequest(); + +private: + /*Vars*/ + JNIEnv *jvm; + jobject session; + + /*Request Methods*/ + jmethodID createRequestMethodId; + + + /*Load method IDS for reuse. MethodIDS do not count against the jref count and do need to be released.*/ + void loadMethodIds(); + void loadGlobalRefs(JNIEnv *env, jobject session); + + /*Grouped methods for returning the matching method signature string for a given interface*/ + const char *getMethodSignature(const char *methodName); +}; + +extern "C" +{ + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/cpp/main/utils/api/transformation/TransformationUtils.cpp b/src/cpp/main/utils/api/transformation/TransformationUtils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..755e83f52c3a48439ecbe21ebf145644cc1f1cd6 --- /dev/null +++ b/src/cpp/main/utils/api/transformation/TransformationUtils.cpp @@ -0,0 +1,79 @@ +#include "TransformationUtils.h" + +#include + +/** + * @author Ryan Berkheimer + */ + +/* Default Constructor */ +TransformationUtils::TransformationUtils(JNIEnv *jvm, jobject transformation, jobject transformationMap, TypeUtils *typeUtils, MapUtils *mapUtils, ListUtils *listUtils) +{ + this->loadGlobalRefs(jvm, transformation, transformationMap, typeUtils, mapUtils, listUtils); + this->loadMethodIds(); +} + +/* Default Destructor */ +TransformationUtils::~TransformationUtils() +{ + try + {} + catch (const std::exception &e) + { + std::cout << e.what(); + } +} + +/* Public API */ + +struct val_map *TransformationUtils::getConstructor() +{ + jobject jMap = this->jvm->CallObjectMethod(this->transformation, this->getConstructorMethodId); + struct val_map *map = (struct val_map *)malloc(sizeof(struct val_map)); + map->jmap = jMap; + return map; +} + +struct record_list *TransformationUtils::getRecords(const char *key) +{ + jobject jList = this->mapUtils->getObjectVal(this->tMap, key); + int count = this->listUtils->getListLength(jList); + struct record_list *records = (struct record_list *)malloc(sizeof(struct record_list)); + records->count = count; + records->jrecords = jList; + return records; +} + +/* Private Methods */ + +void TransformationUtils::loadGlobalRefs(JNIEnv *jvm, jobject transformation, jobject transformationMap, TypeUtils *typeUtils, MapUtils *mapUtils, ListUtils *listUtils) +{ + this->jvm = jvm; + this->transformation = transformation; + this->transformationMap = transformationMap; + this->typeUtils = typeUtils; + this->mapUtils = mapUtils; + this->listUtils = listUtils; + + struct val_map *map = (struct val_map *)malloc(sizeof(struct val_map)); + map->jmap = transformationMap; + this->tMap = map; +} + +void TransformationUtils::loadMethodIds() +{ + jclass transformationClass = JniUtils::getNamedClass(this->jvm, "gov/noaa/messageapi/interfaces/ITransformation"); + + this->getConstructorMethodId = JniUtils::getMethod(this->jvm, transformationClass, "getConstructor", this->getMethodSignature("getConstructor"), false); + + jvm->DeleteLocalRef(transformationClass); +} + +const char *TransformationUtils::getMethodSignature(const char *methodName) +{ + if (strcmp(methodName, "getConstructor") == 0) + { + return "()Ljava/util/Map;"; + } + return NULL; +} \ No newline at end of file diff --git a/src/cpp/main/utils/api/transformation/TransformationUtils.h b/src/cpp/main/utils/api/transformation/TransformationUtils.h new file mode 100644 index 0000000000000000000000000000000000000000..03e3599790a5e795f3c24ae8cbc06b1504cd8a60 --- /dev/null +++ b/src/cpp/main/utils/api/transformation/TransformationUtils.h @@ -0,0 +1,65 @@ +#ifndef _TRANSFORMATIONUTILS_H +#define _TRANSFORMATIONUTILS_H + +#include +#include +#include "messageapi_structs.h" + +#ifdef __cplusplus +#include +#include + +#include "JniUtils.h" +#include "TypeUtils.h" +#include "MapUtils.h" +#include "ListUtils.h" + +/** + * + * @author Ryan Berkheimer + */ +class TransformationUtils +{ + +public: + /*Default constructor */ + TransformationUtils(JNIEnv *jvm, jobject transformation, jobject transformationMap, TypeUtils *typeUtils, MapUtils *mapUtils, ListUtils *listUtils); + + /*Default Destructor */ + ~TransformationUtils(); + + /* Transformation API */ + struct val_map *getConstructor(); + struct record_list *getRecords(const char *key); + +private: + /*Vars*/ + JNIEnv *jvm; + jobject transformation; + jobject transformationMap; + TypeUtils *typeUtils; + MapUtils *mapUtils; + ListUtils *listUtils; + + struct val_map *tMap; + + jmethodID getConstructorMethodId; + + /*Load method IDS for reuse. MethodIDS do not count against the jref count and do need to be released.*/ + void loadMethodIds(); + void loadGlobalRefs(JNIEnv *env, jobject transformation, jobject transformationMap, TypeUtils *typeUtils, MapUtils *mapUtils, ListUtils *listUtils); + + /*Grouped methods for returning the matching method signature string for a given interface*/ + const char *getMethodSignature(const char *methodName); +}; + +extern "C" +{ + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/cpp/main/common/JniUtils.cpp b/src/cpp/main/utils/general/jni/JniUtils.cpp similarity index 92% rename from src/cpp/main/common/JniUtils.cpp rename to src/cpp/main/utils/general/jni/JniUtils.cpp index 67b8e80ed2186198b412d2f4fc2253b635919785..25d4270774878530f9a9b1d0a0255da75af461f3 100644 --- a/src/cpp/main/common/JniUtils.cpp +++ b/src/cpp/main/utils/general/jni/JniUtils.cpp @@ -7,7 +7,7 @@ namespace JniUtils { if (jvm->ExceptionCheck()) { - std::cout << "MessageApiEndpoint.cpp errored with the following message:" << errorMessage << std::endl; + std::cout << "An exception was thrown with the following message:" << errorMessage << std::endl; jclass jException = static_cast(jvm->NewGlobalRef(jvm->FindClass("java/lang/Exception"))); jvm->ThrowNew(jException, errorMessage.c_str()); jvm->DeleteLocalRef(jException); diff --git a/src/cpp/main/common/JniUtils.h b/src/cpp/main/utils/general/jni/JniUtils.h similarity index 99% rename from src/cpp/main/common/JniUtils.h rename to src/cpp/main/utils/general/jni/JniUtils.h index e920e03140fd19e864562ac1c9d2c1dd067bb2b1..b014855cabe1f87c052e46c7d911179108907862 100644 --- a/src/cpp/main/common/JniUtils.h +++ b/src/cpp/main/utils/general/jni/JniUtils.h @@ -1,4 +1,3 @@ - #ifndef _JNIUTILS_H #define _JNIUTILS_H diff --git a/src/cpp/main/common/ListUtils.cpp b/src/cpp/main/utils/general/list/ListUtils.cpp similarity index 95% rename from src/cpp/main/common/ListUtils.cpp rename to src/cpp/main/utils/general/list/ListUtils.cpp index cf79aa0d7630d4c3a2e39aa2051a3a580ee45929..06905c867d372de2c4b87b151413629c8b6bc1ba 100644 --- a/src/cpp/main/common/ListUtils.cpp +++ b/src/cpp/main/utils/general/list/ListUtils.cpp @@ -90,6 +90,14 @@ struct val_list *ListUtils::getListItem(struct val_list *list, int index) return valueList; } +struct val_map *ListUtils::getMapItem(struct val_list *list, int index) +{ + jobject mapItem = this->getObjectItem(list, index); + struct val_map *valMap = (struct val_map *)malloc(sizeof(struct val_map)); + valMap->jmap = mapItem; + return valMap; +} + int ListUtils::getIntItem(struct val_list *list, int index) { jobject list_item = this->getObjectItem(list, index); @@ -236,6 +244,12 @@ void ListUtils::addListItem(struct val_list *list, struct val_list *val) list->count += 1; } +void ListUtils::addMapItem(struct val_list *list, struct val_map *val) +{ + this->jvm->CallVoidMethod(list->jlist, this->addListItemMethod(), val->jmap); + list->count += 1; +} + struct string_list *ListUtils::translateStringList(jobject jList) { int stringCount = this->getListLength(jList); diff --git a/src/cpp/main/common/ListUtils.h b/src/cpp/main/utils/general/list/ListUtils.h similarity index 95% rename from src/cpp/main/common/ListUtils.h rename to src/cpp/main/utils/general/list/ListUtils.h index eab60524e47de47da0da93ab23bf92a8d425f753..6fd62ec268d57df98f569956e9d36484f5882345 100644 --- a/src/cpp/main/common/ListUtils.h +++ b/src/cpp/main/utils/general/list/ListUtils.h @@ -1,4 +1,3 @@ - #ifndef _LISTUTILS_H #define _LISTUTILS_H @@ -44,6 +43,7 @@ public: bool getBoolItem(struct val_list *list, int index); short getShortItem(struct val_list *list, int index); struct val_list *getListItem(struct val_list *list, int index); + struct val_map *getMapItem(struct val_list *list, int index); /*List Item Insertion Methods*/ void addItem(struct val_list *list, struct list_item *item); @@ -57,6 +57,7 @@ public: void addBoolItem(struct val_list *list, bool val); void addShortItem(struct val_list *list, short val); void addListItem(struct val_list *list, struct val_list *val); + void addMapItem(struct val_list *list, struct val_map *map); jmethodID createListMethod(); jmethodID getListSizeMethod(); diff --git a/src/cpp/main/utils/general/map/MapUtils.cpp b/src/cpp/main/utils/general/map/MapUtils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bec29e2e20341b34d4de2543db78fc4c2a9ca207 --- /dev/null +++ b/src/cpp/main/utils/general/map/MapUtils.cpp @@ -0,0 +1,280 @@ +#include "MapUtils.h" + +/* Default Constructor */ +MapUtils::MapUtils(JNIEnv *env, TypeUtils *typeUtils) +{ + this->loadGlobalRefs(env, typeUtils); + this->loadMethodIds(); +} + +/* Default destructor */ +MapUtils::~MapUtils() +{ + try + { + } + catch (const std::exception &e) + { + std::cout << e.what(); + } +} + +void MapUtils::loadGlobalRefs(JNIEnv *env, TypeUtils *typeUtils) +{ + this->jvm = env; + this->typeUtils = typeUtils; +} + +void MapUtils::loadMethodIds() +{ + jclass mapClass = JniUtils::getNamedClass(this->jvm, "java/util/Map"); + + this->getSizeMethodId = this->jvm->GetMethodID(mapClass, "size", "()I"); + this->hasKeyMethodId = this->jvm->GetMethodID(mapClass, "containsKey", "(Ljava/lang/Object;)Z"); + this->getValueMethodId = this->jvm->GetMethodID(mapClass, "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); + this->putValueMethodId = this->jvm->GetMethodID(mapClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); + + this->jvm->DeleteLocalRef(mapClass); + + this->createMapMethodId = this->jvm->GetMethodID(this->typeUtils->getMapClass(), "", "()V"); +} + +jmethodID MapUtils::createMapMethod() +{ + return this->createMapMethodId; +} + +jmethodID MapUtils::getSizeMethod() +{ + return this->getSizeMethodId; +} + +jmethodID MapUtils::hasKeyMethod() +{ + return this->hasKeyMethodId; +} + +jmethodID MapUtils::getValueMethod() +{ + return this->getValueMethodId; +} + +jmethodID MapUtils::putValueMethod() +{ + return this->putValueMethodId; +} + +struct val_map *MapUtils::createMap() +{ + jobject jMap = this->jvm->NewObject(this->typeUtils->getMapClass(), this->createMapMethod()); + struct val_map *valueMap = (struct val_map *)malloc(sizeof(struct val_map)); + valueMap->jmap = jMap; + return valueMap; +} + +int MapUtils::getSize(val_map *val_map) +{ + return (int)this->jvm->CallIntMethod(val_map->jmap, this->getSizeMethod()); +} + +bool MapUtils::hasKey(val_map *val_map, const char *key) +{ + return (bool)this->jvm->CallBooleanMethod(val_map->jmap, this->hasKeyMethod()); +} + +/*Map Value Retrieval Methods*/ +struct map_val *MapUtils::getVal(struct val_map *map, const char *key) +{ + struct map_val *mapVal = (struct map_val *)malloc(sizeof(struct map_val)); + mapVal->jval = this->getObjectVal(map, key); + return mapVal; +} + +jobject MapUtils::getObjectVal(struct val_map *map, const char *key) +{ + jstring jkey = this->typeUtils->toJavaString(key); + jobject objectVal = static_cast(this->jvm->CallObjectMethod(map->jmap, this->getValueMethod(), jkey)); + this->jvm->DeleteLocalRef(jkey); + return objectVal; +} + +int MapUtils::getIntVal(struct val_map *map, const char *key) +{ + jobject jval = this->getObjectVal(map, key); + int val = (int)this->jvm->CallIntMethod(jval, this->typeUtils->getIntMethod()); + jvm->DeleteLocalRef(jval); + return val; +} + +long MapUtils::getLongVal(struct val_map *map, const char *key) +{ + jobject jval = this->getObjectVal(map, key); + long val = (long)this->jvm->CallLongMethod(jval, this->typeUtils->getLongMethod()); + jvm->DeleteLocalRef(jval); + return val; +} + +float MapUtils::getFloatVal(struct val_map *map, const char *key) +{ + jobject jval = this->getObjectVal(map, key); + float val = (float)this->jvm->CallFloatMethod(jval, this->typeUtils->getFloatMethod()); + jvm->DeleteLocalRef(jval); + return val; +} + +double MapUtils::getDoubleVal(struct val_map *map, const char *key) +{ + jobject jval = this->getObjectVal(map, key); + double val = (double)this->jvm->CallDoubleMethod(jval, this->typeUtils->getDoubleMethod()); + jvm->DeleteLocalRef(jval); + return val; +} + +signed char MapUtils::getByteVal(struct val_map *map, const char *key) +{ + jobject jval = this->getObjectVal(map, key); + signed char val = (signed char)this->jvm->CallByteMethod(jval, this->typeUtils->getByteMethod()); + jvm->DeleteLocalRef(jval); + return val; +} + +const char *MapUtils::getStringVal(struct val_map *map, const char *key) +{ + jstring jString = static_cast(this->jvm->CallObjectMethod(map->jmap, this->getValueMethod(), key)); + const char *val = this->typeUtils->fromJavaString(jString); + jvm->DeleteLocalRef(jString); + return val; +} + +bool MapUtils::getBoolVal(struct val_map *map, const char *key) +{ + jobject jval = this->getObjectVal(map, key); + bool val = (bool)this->jvm->CallBooleanMethod(jval, this->typeUtils->getBoolMethod()); + jvm->DeleteLocalRef(jval); + return val; +} + +short MapUtils::getShortVal(struct val_map *map, const char *key) +{ + jobject jval = this->getObjectVal(map, key); + short val = (short)this->jvm->CallShortMethod(jval, this->typeUtils->getShortMethod()); + jvm->DeleteLocalRef(jval); + return val; +} + +struct val_list *MapUtils::getListVal(struct val_map *map, const char *key) +{ + jobject listItem = this->getObjectVal(map, key); + struct val_list *valueList = (struct val_list *)malloc(sizeof(struct val_list)); + valueList->jlist = listItem; + return valueList; +} + +struct val_map *MapUtils::getMapVal(struct val_map *map, const char *key) +{ + jobject jValMap = this->getObjectVal(map, key); + struct val_map *valMap = (struct val_map *)malloc(sizeof(struct val_map)); + valMap->jmap = jValMap; + return valMap; +} + +/*Insert or Update Methods*/ +void MapUtils::putVal(struct val_map *map, const char *key, struct map_val *val) +{ + jstring jKey = this->typeUtils->toJavaString(key); + this->jvm->CallVoidMethod(map->jmap, this->putValueMethod(), jKey, val->jval); + this->jvm->DeleteLocalRef(jKey); +} + +void MapUtils::putObjectVal(struct val_map *map, const char *key, jobject val) +{ + jstring jKey = this->typeUtils->toJavaString(key); + this->jvm->CallVoidMethod(map->jmap, this->putValueMethod(), jKey, val); + this->jvm->DeleteLocalRef(jKey); +} + +void MapUtils::putIntVal(struct val_map *map, const char *key, int val) +{ + jstring jKey = this->typeUtils->toJavaString(key); + jobject jVal = jvm->NewObject(this->typeUtils->getIntClass(), this->typeUtils->createIntMethod(), (jint)val); + this->jvm->CallVoidMethod(map->jmap, this->putValueMethod(), jKey, jVal); + this->jvm->DeleteLocalRef(jKey); + this->jvm->DeleteLocalRef(jVal); +} + +void MapUtils::putLongVal(struct val_map *map, const char *key, long val) +{ + jstring jKey = this->typeUtils->toJavaString(key); + jobject jVal = jvm->NewObject(this->typeUtils->getLongClass(), this->typeUtils->createLongMethod(), (jlong)val); + this->jvm->CallVoidMethod(map->jmap, this->putValueMethod(), jKey, jVal); + this->jvm->DeleteLocalRef(jKey); + this->jvm->DeleteLocalRef(jVal); +} + +void MapUtils::putFloatVal(struct val_map *map, const char *key, float val) +{ + jstring jKey = this->typeUtils->toJavaString(key); + jobject jVal = jvm->NewObject(this->typeUtils->getFloatClass(), this->typeUtils->createFloatMethod(), (jfloat)val); + this->jvm->CallVoidMethod(map->jmap, this->putValueMethod(), jKey, jVal); + this->jvm->DeleteLocalRef(jKey); + this->jvm->DeleteLocalRef(jVal); +} + +void MapUtils::putDoubleVal(struct val_map *map, const char *key, double val) +{ + jstring jKey = this->typeUtils->toJavaString(key); + jobject jVal = jvm->NewObject(this->typeUtils->getDoubleClass(), this->typeUtils->createDoubleMethod(), (jdouble)val); + this->jvm->CallVoidMethod(map->jmap, this->putValueMethod(), jKey, jVal); + this->jvm->DeleteLocalRef(jKey); + this->jvm->DeleteLocalRef(jVal); +} + +void MapUtils::putByteVal(struct val_map *map, const char *key, signed char val) +{ + jstring jKey = this->typeUtils->toJavaString(key); + jobject jVal = jvm->NewObject(this->typeUtils->getByteClass(), this->typeUtils->createByteMethod(), (jbyte)val); + this->jvm->CallVoidMethod(map->jmap, this->putValueMethod(), jKey, jVal); + this->jvm->DeleteLocalRef(jKey); + this->jvm->DeleteLocalRef(jVal); +} + +void MapUtils::putStringVal(struct val_map *map, const char *key, const char *val) +{ + jstring jKey = this->typeUtils->toJavaString(key); + jstring jVal = this->typeUtils->toJavaString(val); + this->jvm->CallVoidMethod(map->jmap, this->putValueMethod(), jKey, jVal); + this->jvm->DeleteLocalRef(jKey); + this->jvm->DeleteLocalRef(jVal); +} + +void MapUtils::putBoolVal(struct val_map *map, const char *key, bool val) +{ + jstring jKey = this->typeUtils->toJavaString(key); + jobject jVal = jvm->NewObject(this->typeUtils->getBoolClass(), this->typeUtils->createBoolMethod(), (jboolean)val); + this->jvm->CallVoidMethod(map->jmap, this->putValueMethod(), jKey, jVal); + this->jvm->DeleteLocalRef(jKey); + this->jvm->DeleteLocalRef(jVal); +} + +void MapUtils::putShortVal(struct val_map *map, const char *key, short val) +{ + jstring jKey = this->typeUtils->toJavaString(key); + jobject jVal = jvm->NewObject(this->typeUtils->getShortClass(), this->typeUtils->createShortMethod(), (jshort)val); + this->jvm->CallVoidMethod(map->jmap, this->putValueMethod(), jKey, jVal); + this->jvm->DeleteLocalRef(jKey); + this->jvm->DeleteLocalRef(jVal); +} + +void MapUtils::putListVal(struct val_map *map, const char *key, struct val_list *val) +{ + jstring jKey = this->typeUtils->toJavaString(key); + this->jvm->CallVoidMethod(map->jmap, this->putValueMethod(), jKey, val->jlist); + this->jvm->DeleteLocalRef(jKey); +} + +void MapUtils::putMapVal(struct val_map *map, const char *key, struct val_map *val) +{ + jstring jKey = this->typeUtils->toJavaString(key); + this->jvm->CallVoidMethod(map->jmap, this->putValueMethod(), jKey, val->jmap); + this->jvm->DeleteLocalRef(jKey); +} diff --git a/src/cpp/main/utils/general/map/MapUtils.h b/src/cpp/main/utils/general/map/MapUtils.h new file mode 100644 index 0000000000000000000000000000000000000000..b81ecf77f17faa0d8b108386ae64823946d5867b --- /dev/null +++ b/src/cpp/main/utils/general/map/MapUtils.h @@ -0,0 +1,96 @@ +#ifndef _MAPUTILS_H +#define _MAPUTILS_H + +#include +#include "messageapi_structs.h" + +#ifdef __cplusplus + +#include +#include + +#include "JniUtils.h" +#include "TypeUtils.h" +#include "ListUtils.h" + +/** + * This is the header for the MapUtils object class. MapUtils contains a set of methods used for manipulation of Java Maps + * in C++ or C code. MapUtils is a class to be instantiated so that it remains thread safe for implementors. + */ +class MapUtils +{ + +public: + /* Default constructor for ListUtils */ + MapUtils(JNIEnv *env, TypeUtils *typeUtils); + + /* Default destructor for ListUtils */ + ~MapUtils(); + + /* Utility methods */ + struct val_map *createMap(); + int getSize(struct val_map *map); + bool hasKey(struct val_map *map, const char *key); + + /*Map Value Retrieval Methods*/ + struct map_val *getVal(struct val_map *map, const char *key); + jobject getObjectVal(struct val_map *map, const char *key); + int getIntVal(struct val_map *map, const char *key); + long getLongVal(struct val_map *map, const char *key); + float getFloatVal(struct val_map *map, const char *key); + double getDoubleVal(struct val_map *map, const char *key); + signed char getByteVal(struct val_map *map, const char *key); + const char *getStringVal(struct val_map *map, const char *key); + bool getBoolVal(struct val_map *map, const char *key); + short getShortVal(struct val_map *map, const char *key); + struct val_list *getListVal(struct val_map *map, const char *key); + struct val_map *getMapVal(struct val_map *map, const char *key); + + /*Insert or Update Methods*/ + void putVal(struct val_map *map, const char *key, struct map_val *val); + void putObjectVal(struct val_map *map, const char *key, jobject val); + void putIntVal(struct val_map *map, const char *key, int val); + void putLongVal(struct val_map *map, const char *key, long val); + void putFloatVal(struct val_map *map, const char *key, float val); + void putDoubleVal(struct val_map *map, const char *key, double val); + void putByteVal(struct val_map *map, const char *key, signed char val); + void putStringVal(struct val_map *map, const char *key, const char *val); + void putBoolVal(struct val_map *map, const char *key, bool val); + void putShortVal(struct val_map *map, const char *key, short val); + void putListVal(struct val_map *map, const char *key, struct val_list *val); + void putMapVal(struct val_map *map, const char *key, struct val_map *val); + + jmethodID createMapMethod(); + jmethodID getSizeMethod(); + jmethodID hasKeyMethod(); + jmethodID getValueMethod(); + jmethodID putValueMethod(); + + +private: + JNIEnv *jvm; + TypeUtils *typeUtils; + ListUtils *listUtils; + + jmethodID createMapMethodId; + jmethodID getSizeMethodId; + jmethodID hasKeyMethodId; + jmethodID getValueMethodId; + jmethodID putValueMethodId; + + /* Initialization Methods */ + void loadGlobalRefs(JNIEnv *env, TypeUtils *TypeUtils); + void loadMethodIds(); + +}; + +extern "C" +{ + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/cpp/main/common/TypeUtils.cpp b/src/cpp/main/utils/general/type/TypeUtils.cpp similarity index 96% rename from src/cpp/main/common/TypeUtils.cpp rename to src/cpp/main/utils/general/type/TypeUtils.cpp index 7617b69ae5cd44e8323af84ab2f3c02ef91e7a1b..d2596ebeefaefb7500883ab8cc565d5472e82b63 100644 --- a/src/cpp/main/common/TypeUtils.cpp +++ b/src/cpp/main/utils/general/type/TypeUtils.cpp @@ -10,6 +10,7 @@ TypeUtils::~TypeUtils() { try { + this->jvm->DeleteGlobalRef(this->mapClass); this->jvm->DeleteGlobalRef(this->listClass); this->jvm->DeleteGlobalRef(this->intClass); this->jvm->DeleteGlobalRef(this->longClass); @@ -30,6 +31,7 @@ void TypeUtils::loadGlobalRefs(JNIEnv *env) { this->jvm = env; + this->mapClass = JniUtils::getGlobalClassRef(env, "java/util/HashMap"); this->listClass = JniUtils::getGlobalClassRef(env, "java/util/ArrayList"); this->intClass = JniUtils::getGlobalClassRef(env, "java/lang/Integer"); @@ -206,3 +208,8 @@ jclass TypeUtils::getListClass() { return this->listClass; } + +jclass TypeUtils::getMapClass() +{ + return this->mapClass; +} diff --git a/src/cpp/main/common/TypeUtils.h b/src/cpp/main/utils/general/type/TypeUtils.h similarity index 98% rename from src/cpp/main/common/TypeUtils.h rename to src/cpp/main/utils/general/type/TypeUtils.h index 54719a00756378906c037e01bf22e48d4e6bca80..e48f398c4b720136f295bbf7043202af10581190 100644 --- a/src/cpp/main/common/TypeUtils.h +++ b/src/cpp/main/utils/general/type/TypeUtils.h @@ -1,4 +1,3 @@ - #ifndef _TYPEUTILS_H #define _TYPEUTILS_H @@ -52,6 +51,7 @@ public: jclass getShortClass(); jclass getListClass(); + jclass getMapClass(); jstring toJavaString(const char *charString); const char *fromJavaString(jstring javaString); @@ -72,6 +72,7 @@ private: jclass shortClass; jclass listClass; + jclass mapClass; /*Type Utility Retrieval Methods*/ jmethodID getBoolMethodId; diff --git a/src/groovy/test/endtoend/FileReaderTests.groovy b/src/groovy/test/endtoend/FileReaderTests.groovy index ee658d3b5417ebb8453f9cefb9ed27295660af65..7c59d576cc8a4dfb183950acd9512587c96c251f 100644 --- a/src/groovy/test/endtoend/FileReaderTests.groovy +++ b/src/groovy/test/endtoend/FileReaderTests.groovy @@ -15,7 +15,7 @@ import gov.noaa.messageapi.sessions.DefaultSession; class FileReaderTests extends spock.lang.Specification { -def "Tests submission of a full file reader task with 1 small input."() { +/*def "Tests submission of a full file reader task with 1 small input."() { given: "A standard condition test request" ISession session = new DefaultSession("{}/resources/test/file-reader/manifest.json") IRequest request = session.createRequest(); @@ -27,7 +27,7 @@ def "Tests submission of a full file reader task with 1 small input."() { then: "We should have no rejections and there should be 7 records in the return set." response.getRejections().size() == 0 response.getRecords().size() == 7 - } + }*/ def "Tests submission of a full file reader task with 1 large input."() { given: "A standard condition test request" @@ -39,6 +39,8 @@ def "Tests submission of a full file reader task with 1 large input."() { IResponse response = request.submit(); while (!response.isComplete()) {} then: "We should have no rejections and there should be 79794 records in the return set." + //println "FIELD VALUE!!!" + //println response.getRecords().get(0).getField("value").getValue() response.getRejections().size() == 0 response.getRecords().size() == 79794 } diff --git a/src/groovy/test/endtoend/NativeEndpointTests.groovy b/src/groovy/test/endtoend/NativeEndpointTests.groovy index e2504ed8e454ac7d6142d1a82ead6e9db4afdafd..6263382b1456dd7ee7e829bd1629ebb1fd64e425 100644 --- a/src/groovy/test/endtoend/NativeEndpointTests.groovy +++ b/src/groovy/test/endtoend/NativeEndpointTests.groovy @@ -28,7 +28,7 @@ def 'Session with one endpoint that calls into C, populates a return record, and record1.setField('null-test', 'null') record2.setField('string-test', 'cool!') record2.setField('initial-value', 5000) - record2.setField('null-test', 'null') + //record2.setField('null-test', 'null') /*for (int i=0; i<500; i++) { IRecord r = request.createRecord(); r.setField("initial-value", i); @@ -39,15 +39,8 @@ def 'Session with one endpoint that calls into C, populates a return record, and IResponse response = request.submit() while (!response.isComplete()) { } then: 'No rejections, one return record, field values match..' - println "finished!!!!" response.getRejections().size() == 0 - println "rejection size:" - println response.getRejections().size() - println "record size:" - println response.getRecords().size() response.getRecords().size() == 1 - println "test-integer value:" - println response.getRecords().get(0).getField('test-integer').getValue() response.getRecords().get(0).getField('test-integer').getValue() == 5 response.getRecords().get(0).getField('return-list').getValue().get(0) == "first element of our string!" response.getRecords().get(0).getField('return-list').getValue().get(1) == "second element of our string!!" diff --git a/src/groovy/test/endtoend/NativeTransformationTests.groovy b/src/groovy/test/endtoend/NativeTransformationTests.groovy new file mode 100644 index 0000000000000000000000000000000000000000..263d794e72baf8d07fddf3426b7d566372c63ef4 --- /dev/null +++ b/src/groovy/test/endtoend/NativeTransformationTests.groovy @@ -0,0 +1,49 @@ +/** + * Tests sessions that use the native transformation. This is an end to end type testing module. + * @author Ryan Berkheimer + */ + +import java.util.List + +import gov.noaa.messageapi.interfaces.ISession +import gov.noaa.messageapi.interfaces.IRequest +import gov.noaa.messageapi.interfaces.IResponse +import gov.noaa.messageapi.interfaces.IRejection +import gov.noaa.messageapi.interfaces.IRecord +import gov.noaa.messageapi.interfaces.IField + +import gov.noaa.messageapi.sessions.DefaultSession + +class NativeTransformationTests extends spock.lang.Specification { + +def 'Session with one endpoint that calls into C, populates a return record, and checks vals.'() { + given: 'A session created based on a native counter' + ISession session = new DefaultSession('{}/resources/test/native-transformation/manifest.json') + IRequest request = session.createRequest() + IRecord record1 = request.createRecord() + IRecord record2 = request.createRecord() + + record1.setField('initial-value', 1000) + record1.setField('string-test', 'hi there!') + record1.setField('null-test', 'null') + record2.setField('string-test', 'cool!') + record2.setField('initial-value', 5000) + //record2.setField('null-test', 'null') + /*for (int i=0; i<500; i++) { + IRecord r = request.createRecord(); + r.setField("initial-value", i); + r.setField("string-test", Integer.toString(i)); + }*/ + + when: 'Submit the request, call a transformation in the evaluation endpoint, return all records' + IResponse response = request.submit() + while (!response.isComplete()) { } + then: 'No rejections, two return records, field values match..' + response.getRejections().size() == 0 + response.getRecords().size() == 2 + //response.getRecords().get(0).getField('test-integer').getValue() == 5 + //response.getRecords().get(0).getField('return-list').getValue().get(0) == "first element of our string!" + //response.getRecords().get(0).getField('return-list').getValue().get(1) == "second element of our string!!" + } + +} diff --git a/src/java/main/gov/noaa/messageapi/conditions/ComparisonCondition.java b/src/java/main/gov/noaa/messageapi/conditions/ComparisonCondition.java index f8b84373680d26b90d79429cc6807e2e26c5238a..4057dc8f86ae1e8321657ed214c302e20b9e7213 100644 --- a/src/java/main/gov/noaa/messageapi/conditions/ComparisonCondition.java +++ b/src/java/main/gov/noaa/messageapi/conditions/ComparisonCondition.java @@ -2,7 +2,6 @@ package gov.noaa.messageapi.conditions; import java.util.Map; -import gov.noaa.messageapi.conditions.BaseCondition; import gov.noaa.messageapi.interfaces.IComparisonCondition;; /** diff --git a/src/java/main/gov/noaa/messageapi/conditions/CompositeCondition.java b/src/java/main/gov/noaa/messageapi/conditions/CompositeCondition.java index 4a6ce17d911e815e655c84a4a3ddc15a31752e88..72c59127bd91d691656a254cc2761d094bf550d7 100644 --- a/src/java/main/gov/noaa/messageapi/conditions/CompositeCondition.java +++ b/src/java/main/gov/noaa/messageapi/conditions/CompositeCondition.java @@ -3,7 +3,6 @@ package gov.noaa.messageapi.conditions; import java.util.List; import java.util.Map; -import gov.noaa.messageapi.conditions.BaseCondition; import gov.noaa.messageapi.interfaces.ICompositeCondition; /** diff --git a/src/java/main/gov/noaa/messageapi/connections/DefaultConnection.java b/src/java/main/gov/noaa/messageapi/connections/DefaultConnection.java index 309e140e1dbde8841fcd5d57da7f5fdaa7bd97ba..f62a83c02af5fa14cf4afaf4b045c381fdec8725 100644 --- a/src/java/main/gov/noaa/messageapi/connections/DefaultConnection.java +++ b/src/java/main/gov/noaa/messageapi/connections/DefaultConnection.java @@ -9,7 +9,6 @@ import java.util.UUID; import gov.noaa.messageapi.interfaces.IConnection; import gov.noaa.messageapi.interfaces.IPacket; import gov.noaa.messageapi.interfaces.IProtocolRecord; -import gov.noaa.messageapi.interfaces.ITransformationFactory; import gov.noaa.messageapi.definitions.ContainerDefinition; @@ -44,8 +43,7 @@ public class DefaultConnection extends BaseConnection implements IConnection { this.setClassifiers(new HashMap>()); } if (connectionMap.containsKey("transformations")) { - this.integrateTransformations((List) connectionMap.get("transformations"), - containerDefinition.getTransformationFactory(), containerDefinition.getTransformationMaps()); + this.integrateTransformations((List) connectionMap.get("transformations"), containerDefinition.getTransformationMaps()); } else { this.setTransformationMap(new HashMap>()); } @@ -178,16 +176,15 @@ public class DefaultConnection extends BaseConnection implements IConnection { * are parent transformations of named transformations, as well as classifiers and connections * used by any transformation. * @param transformations The named transformations included on the connection spec itself - * @param transformationFactory A class factory that contains key/value pairs of transformation operator keywords and class references * @param rawTransformationMaps The raw transformation maps containing entire transformation specifications */ - private void integrateTransformations(List transformations,ITransformationFactory transformationFactory, List> rawTransformationMaps) { + private void integrateTransformations(List transformations, List> rawTransformationMaps) { List allTransformationIds = ConnectionUtils.getAllTransformationIds(transformations, rawTransformationMaps); List transformationCollections = ConnectionUtils.getTransformationCollections(allTransformationIds, rawTransformationMaps); Map> transformationClassifiers = ConnectionUtils.getTransformationClassifiers(allTransformationIds, rawTransformationMaps); Map> transformationMap = ConnectionUtils.buildTransformationMap(allTransformationIds, - rawTransformationMaps, transformationFactory); + rawTransformationMaps); this.addCollections(transformationCollections); this.addClassifiers(transformationClassifiers); this.setTransformationMap(transformationMap); diff --git a/src/java/main/gov/noaa/messageapi/containers/DefaultContainer.java b/src/java/main/gov/noaa/messageapi/containers/DefaultContainer.java index 6421017387968e3c59c5754be0639f2744e0e795..36d6dbe4a1a4145cb720cab745de63dff71003dc 100644 --- a/src/java/main/gov/noaa/messageapi/containers/DefaultContainer.java +++ b/src/java/main/gov/noaa/messageapi/containers/DefaultContainer.java @@ -6,7 +6,6 @@ import gov.noaa.messageapi.interfaces.ISchema; import gov.noaa.messageapi.interfaces.IProtocol; import gov.noaa.messageapi.interfaces.IContainer; -import gov.noaa.messageapi.containers.BaseContainer; import gov.noaa.messageapi.metadata.DefaultMetadata; /** diff --git a/src/java/main/gov/noaa/messageapi/definitions/ContainerDefinition.java b/src/java/main/gov/noaa/messageapi/definitions/ContainerDefinition.java index 3bedd104bf200a90adb2df2a49d916d6b5c217d6..b5fbea906689026e3e28cf2e227d8435939c116e 100644 --- a/src/java/main/gov/noaa/messageapi/definitions/ContainerDefinition.java +++ b/src/java/main/gov/noaa/messageapi/definitions/ContainerDefinition.java @@ -6,12 +6,10 @@ import java.util.HashMap; import java.util.ArrayList; import java.util.stream.Collectors; -import gov.noaa.messageapi.interfaces.ITransformationFactory; import gov.noaa.messageapi.parsers.containers.MetadataParser; import gov.noaa.messageapi.parsers.containers.CollectionParser; import gov.noaa.messageapi.parsers.containers.TransformationParser; -import gov.noaa.messageapi.parsers.containers.TransformationFactoryParser; /** * A container definition holds the definition of a container. It essentially @@ -26,16 +24,10 @@ public class ContainerDefinition { private Map metadataMap = null; private List> collectionMaps = null; private List> transformationMaps = null; - private ITransformationFactory transformationFactory = null; private List collections = null; private List transformations = null; private List> classifiers = null; - - private static final String DEFAULT_TRANSFORMATION_FACTORY = - "gov.noaa.messageapi.factories.SimpleTransformationFactory"; - - @SuppressWarnings("unchecked") public ContainerDefinition(Map properties) throws Exception { if (properties.containsKey("metadata")) { @@ -64,9 +56,6 @@ public class ContainerDefinition { this.transformationMaps = new ArrayList>(definition.getTransformationMaps()); } - private void createTransformationFactory(String transformationClass) throws Exception { - this.transformationFactory = TransformationFactoryParser.build(transformationClass); - } private void parseMetadataSpec(String spec) throws Exception { MetadataParser parser = new MetadataParser(spec); @@ -85,11 +74,6 @@ public class ContainerDefinition { TransformationParser parser = new TransformationParser(transformationSpec.get("map")); this.transformationMaps = parser.getTransformationMaps(); this.transformations = parser.getTransformations(); - if (transformationSpec.containsKey("factory")) { - this.createTransformationFactory((String) transformationSpec.get("factory")); - } else { - this.createTransformationFactory(DEFAULT_TRANSFORMATION_FACTORY); - } } else { this.setEmptyTransformationMaps(); } @@ -123,10 +107,6 @@ public class ContainerDefinition { return this.transformationMaps; } - public ITransformationFactory getTransformationFactory() { - return this.transformationFactory; - } - /** * Sets the definition transformation maps to be empty, the transformation * factory to be the default. @@ -134,7 +114,6 @@ public class ContainerDefinition { private void setEmptyTransformationMaps() throws Exception { this.transformationMaps = new ArrayList>(); this.transformations = new ArrayList(); - this.createTransformationFactory(DEFAULT_TRANSFORMATION_FACTORY); } /** diff --git a/src/java/main/gov/noaa/messageapi/endpoints/BaseEndpoint.java b/src/java/main/gov/noaa/messageapi/endpoints/BaseEndpoint.java index 0a698f68072064f16dfc8505fe5126ffe47915db..0aa415c5a9a348fb6d4df5831714ac441bd20123 100644 --- a/src/java/main/gov/noaa/messageapi/endpoints/BaseEndpoint.java +++ b/src/java/main/gov/noaa/messageapi/endpoints/BaseEndpoint.java @@ -26,10 +26,12 @@ public abstract class BaseEndpoint { public List collectionIds = null; public List> classifierIds = null; public List transformationIds = null; + public Map constructorMap = null; @SuppressWarnings("unchecked") public BaseEndpoint(Map parameters) { Map internalParameters = (Map)parameters.get("__internal__"); + this.setConstructor(parameters); this.setFields((List)internalParameters.get("fields"), this.getDefaultFields()); this.setCollectionIds((List)internalParameters.get("collections")); this.setClassifierIds((List>)internalParameters.get("classifiers")); @@ -38,6 +40,10 @@ public abstract class BaseEndpoint { protected abstract List getDefaultFields(); + public Map getConstructor() { + return this.constructorMap; + } + public IPacket createPacket() { return new DefaultPacket(); } @@ -62,6 +68,10 @@ public abstract class BaseEndpoint { return this.transformationIds; } + private void setConstructor(Map constructorMap) { + this.constructorMap = constructorMap; + } + private List getFields() { return this.fields; } diff --git a/src/java/main/gov/noaa/messageapi/endpoints/EvaluationEndpoint.java b/src/java/main/gov/noaa/messageapi/endpoints/EvaluationEndpoint.java index a4ff91aa3d5b60e5ea3897ef7c8e35eb66d37b19..d959d00f7d757629620f8edf0672cacf079f2eb0 100644 --- a/src/java/main/gov/noaa/messageapi/endpoints/EvaluationEndpoint.java +++ b/src/java/main/gov/noaa/messageapi/endpoints/EvaluationEndpoint.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.ArrayList; import java.util.stream.Collectors; +import gov.noaa.messageapi.interfaces.IEndpoint; import gov.noaa.messageapi.interfaces.IField; import gov.noaa.messageapi.interfaces.IPacket; import gov.noaa.messageapi.interfaces.IRecord; @@ -29,7 +30,7 @@ import gov.noaa.messageapi.utils.general.ListUtils; * * @author Ryan Berkheimer */ -public class EvaluationEndpoint extends BaseEndpoint { +public class EvaluationEndpoint extends BaseEndpoint implements IEndpoint { public EvaluationEndpoint(Map parameters) { super(parameters); diff --git a/src/java/main/gov/noaa/messageapi/endpoints/NativeEndpoint.java b/src/java/main/gov/noaa/messageapi/endpoints/NativeEndpoint.java index 09d0b98b5944ea52c36a291935642684d6b66a97..d4e03ef32ef419fa0ec5321dbb978e6a29b0c414 100644 --- a/src/java/main/gov/noaa/messageapi/endpoints/NativeEndpoint.java +++ b/src/java/main/gov/noaa/messageapi/endpoints/NativeEndpoint.java @@ -11,7 +11,6 @@ import gov.noaa.messageapi.interfaces.IField; import gov.noaa.messageapi.interfaces.IPacket; import gov.noaa.messageapi.interfaces.IProtocolRecord; -import gov.noaa.messageapi.endpoints.BaseEndpoint; import gov.noaa.messageapi.fields.DefaultField; import gov.noaa.messageapi.records.schema.SchemaRecord; import gov.noaa.messageapi.rejections.DefaultRejection; diff --git a/src/java/main/gov/noaa/messageapi/factories/SimpleTransformationFactory.java b/src/java/main/gov/noaa/messageapi/factories/SimpleTransformationFactory.java deleted file mode 100644 index 72272e47dc3ca908a3eecd2e53938d7e1835cdc3..0000000000000000000000000000000000000000 --- a/src/java/main/gov/noaa/messageapi/factories/SimpleTransformationFactory.java +++ /dev/null @@ -1,32 +0,0 @@ -package gov.noaa.messageapi.factories; - -import java.util.Map; -import java.util.List; - -import gov.noaa.messageapi.interfaces.ITransformation; -import gov.noaa.messageapi.interfaces.ITransformationFactory; - -import gov.noaa.messageapi.transformations.joins.StringFieldJoin; -import gov.noaa.messageapi.transformations.reductions.ReduceTransformation; - -/** - * @author Ryan Berkheimer - */ -public class SimpleTransformationFactory implements ITransformationFactory { - - /** - * Returns an operator based on a data type name as a string. - * @param type The type of operator to return - * @return A new operator based on the specified type - */ - public ITransformation getTransformation(String type, List fields, Map params) { - switch (type) { - case "join": - return new StringFieldJoin(fields, params); - case "reduce": - return new ReduceTransformation(fields, params); - } - return null; - } - -} diff --git a/src/java/main/gov/noaa/messageapi/fields/DefaultField.java b/src/java/main/gov/noaa/messageapi/fields/DefaultField.java index 4e362451040238a36db4ed028a8a7ade404d2e98..7f98448f66190787b2396699c814df9dff184956 100644 --- a/src/java/main/gov/noaa/messageapi/fields/DefaultField.java +++ b/src/java/main/gov/noaa/messageapi/fields/DefaultField.java @@ -67,15 +67,15 @@ public class DefaultField implements IField { return this.type; } - public boolean isRequired() { + public Boolean isRequired() { return this.required; } - public boolean isValid() { + public Boolean isValid() { return this.valid; } - public void setValid(boolean valid) { + public void setValid(Boolean valid) { this.valid = valid; } diff --git a/src/java/main/gov/noaa/messageapi/interfaces/IComparisonCondition.java b/src/java/main/gov/noaa/messageapi/interfaces/IComparisonCondition.java index 67388160bf458a862ef5edfbf710f87d61bb77d7..a95b548ed3086b1079a48164e5acf8e9a376580c 100644 --- a/src/java/main/gov/noaa/messageapi/interfaces/IComparisonCondition.java +++ b/src/java/main/gov/noaa/messageapi/interfaces/IComparisonCondition.java @@ -1,6 +1,5 @@ package gov.noaa.messageapi.interfaces; -import gov.noaa.messageapi.interfaces.ICondition; /** * ComparisonConditions represent value-checking comparisons. diff --git a/src/java/main/gov/noaa/messageapi/interfaces/ICompositeCondition.java b/src/java/main/gov/noaa/messageapi/interfaces/ICompositeCondition.java index 08df96130bae16ee4fce22cfa4d2cddc38a4564d..20d95e66b29730cf6d484c3fde93591e4adbca9f 100644 --- a/src/java/main/gov/noaa/messageapi/interfaces/ICompositeCondition.java +++ b/src/java/main/gov/noaa/messageapi/interfaces/ICompositeCondition.java @@ -1,7 +1,6 @@ package gov.noaa.messageapi.interfaces; import java.util.List; -import gov.noaa.messageapi.interfaces.ICondition; /** * A composite condition is a type of condition that combines other diff --git a/src/java/main/gov/noaa/messageapi/interfaces/IContainer.java b/src/java/main/gov/noaa/messageapi/interfaces/IContainer.java index de7176559875d109f89fa4ed56e3a5e56cc1abcb..afe485dc90f13404b04b2c9c8d7b20f57425fe68 100644 --- a/src/java/main/gov/noaa/messageapi/interfaces/IContainer.java +++ b/src/java/main/gov/noaa/messageapi/interfaces/IContainer.java @@ -1,6 +1,5 @@ package gov.noaa.messageapi.interfaces; -import gov.noaa.messageapi.interfaces.IComponent; import gov.noaa.messageapi.definitions.ContainerDefinition; /** diff --git a/src/java/main/gov/noaa/messageapi/interfaces/IEndpoint.java b/src/java/main/gov/noaa/messageapi/interfaces/IEndpoint.java index 047e2e7d5fc9899f1a33a30e3e79d3f51d026b0e..cfe1c8e6d8d09cc67b9470556b7be048fa6bf169 100644 --- a/src/java/main/gov/noaa/messageapi/interfaces/IEndpoint.java +++ b/src/java/main/gov/noaa/messageapi/interfaces/IEndpoint.java @@ -1,6 +1,7 @@ package gov.noaa.messageapi.interfaces; import java.util.List; +import java.util.Map; //import gov.noaa.messageapi.interfaces.IPacket; //import gov.noaa.messageapi.interfaces.IProtocolRecord; @@ -38,6 +39,13 @@ public interface IEndpoint { */ public List getDefaultFields(); + /** + * Returns the constructor map attached to the endpoint. The constructor map + * should be used to retrieve constructor parameters. Note that thread safety + * cannot be guaranteed if these parameters are used as read only. + */ + public Map getConstructor(); + /** * Creates a new packet for returning from the endpoint. As all * processing for endpoints must return a packet, all endpoints diff --git a/src/java/main/gov/noaa/messageapi/interfaces/IField.java b/src/java/main/gov/noaa/messageapi/interfaces/IField.java index b19adb2c8e6b12160aec4cbc2d9482f2538dfaf4..8f9f737a24401f479f3cabb813fe181f8ccff494 100644 --- a/src/java/main/gov/noaa/messageapi/interfaces/IField.java +++ b/src/java/main/gov/noaa/messageapi/interfaces/IField.java @@ -34,14 +34,14 @@ public interface IField { * Used contextually to determine whether * or not this field is required for subsequent processing. */ - public boolean isRequired(); + public Boolean isRequired(); /** * Used contextually to determine whether or not * this field is valid. This could be used in type validation * or some other way. */ - public boolean isValid(); + public Boolean isValid(); /** * Returns the value of the field. @@ -58,7 +58,7 @@ public interface IField { * Sets true or false whether or not the field is * valid against some generalized criteria */ - public void setValid(boolean valid); + public void setValid(Boolean valid); /** * Allows setting of the type of the field as a string. diff --git a/src/java/main/gov/noaa/messageapi/interfaces/IProtocol.java b/src/java/main/gov/noaa/messageapi/interfaces/IProtocol.java index 3336f9155fa616ac88cc4fdcebb8dc50a22e5d16..f4750c0c3a6d00797ccad14b85ca0989ff663fce 100644 --- a/src/java/main/gov/noaa/messageapi/interfaces/IProtocol.java +++ b/src/java/main/gov/noaa/messageapi/interfaces/IProtocol.java @@ -2,7 +2,6 @@ package gov.noaa.messageapi.interfaces; import java.util.List; -import gov.noaa.messageapi.interfaces.IComponent; import gov.noaa.messageapi.definitions.ProtocolDefinition; /** diff --git a/src/java/main/gov/noaa/messageapi/interfaces/IResponse.java b/src/java/main/gov/noaa/messageapi/interfaces/IResponse.java index f766e7f382f798403d6e4842334d746092c650ab..5a4661a007b2bca57dd46ef1225ef3013cbf4f50 100644 --- a/src/java/main/gov/noaa/messageapi/interfaces/IResponse.java +++ b/src/java/main/gov/noaa/messageapi/interfaces/IResponse.java @@ -9,7 +9,7 @@ import java.util.List; * any processing steps (validation, factoring, transformation, etc.) * in sequence, eventually yielding a set of returned data packets from * endpoint connections, where it combines them and sets a response - * list of records, list of rejections, and changes the isComplete boolean + * list of records, list of rejections, and changes the isComplete Boolean * to true. * @author Ryan Berkheimer */ @@ -19,7 +19,7 @@ public interface IResponse { * Returns true or false, depending on if all processing * within the response is complete. */ - public Boolean isComplete(); + public boolean isComplete(); /** * Returns the associated request that the response is @@ -59,7 +59,7 @@ public interface IResponse { * there are no more records or rejections coming through for the current * submission. */ - public void setComplete(Boolean isComplete); + public void setComplete(boolean isComplete); } diff --git a/src/java/main/gov/noaa/messageapi/interfaces/ISchema.java b/src/java/main/gov/noaa/messageapi/interfaces/ISchema.java index 789f7a8c5b3e7eb8ef40bc6813d870b56104e8a4..c3b6a7a0cfa47b7e3aa8954957e63b9df9bdd191 100644 --- a/src/java/main/gov/noaa/messageapi/interfaces/ISchema.java +++ b/src/java/main/gov/noaa/messageapi/interfaces/ISchema.java @@ -1,7 +1,5 @@ package gov.noaa.messageapi.interfaces; -import gov.noaa.messageapi.interfaces.IComponent; - import gov.noaa.messageapi.definitions.SchemaDefinition; /** diff --git a/src/java/main/gov/noaa/messageapi/interfaces/ITransformation.java b/src/java/main/gov/noaa/messageapi/interfaces/ITransformation.java index d1400a0c70c340ced3bcd67e97718b9ccd19ea3f..fb260cc6dde8e29a2187a377f688c432c73e6bbd 100644 --- a/src/java/main/gov/noaa/messageapi/interfaces/ITransformation.java +++ b/src/java/main/gov/noaa/messageapi/interfaces/ITransformation.java @@ -8,6 +8,21 @@ import java.util.List; */ public interface ITransformation { + /** + * The process method takes in a map of string and record mappings and is + * the main runtime method for the transformation. These mapping + * definitions are contained in the parameter spec. Note that transformations + * are immutable assuming that a getCopy method is provided to any + * custom user types, and this means that individual records may be manipulated + * as desired and returned as needed in the transformation. + */ public List process(Map> transformationMap); + /** + * Returns the constructor map attached to the transformation. The constructor map + * can be used to retrieve constructor parameters. Note that thread safety + * cannot be guaranteed if these parameters are used for anything other than read only. + */ + public Map getConstructor(); + } diff --git a/src/java/main/gov/noaa/messageapi/interfaces/ITransformationFactory.java b/src/java/main/gov/noaa/messageapi/interfaces/ITransformationFactory.java deleted file mode 100644 index af502cc7a0ee67706930ef8df49b8e655e806985..0000000000000000000000000000000000000000 --- a/src/java/main/gov/noaa/messageapi/interfaces/ITransformationFactory.java +++ /dev/null @@ -1,13 +0,0 @@ -package gov.noaa.messageapi.interfaces; - -import java.util.Map; -import java.util.List; - -/** - * @author Ryan Berkheimer - */ -public interface ITransformationFactory { - - public ITransformation getTransformation(String id, List fields, Map params); - -} diff --git a/src/java/main/gov/noaa/messageapi/operators/conditions/BooleanConditionOperator.java b/src/java/main/gov/noaa/messageapi/operators/conditions/BooleanConditionOperator.java index 93d49b8d58c0c8b900b6c2a365a6267bc7318f84..ac5de9e15eb26213f5f2e89f78ad274e88bd8658 100644 --- a/src/java/main/gov/noaa/messageapi/operators/conditions/BooleanConditionOperator.java +++ b/src/java/main/gov/noaa/messageapi/operators/conditions/BooleanConditionOperator.java @@ -3,7 +3,6 @@ package gov.noaa.messageapi.operators.conditions; import gov.noaa.messageapi.interfaces.IConditionOperator; import gov.noaa.messageapi.interfaces.IField; import gov.noaa.messageapi.interfaces.ICondition; -import gov.noaa.messageapi.operators.conditions.SimpleConditionOperator; /** * @author Ryan Berkheimer diff --git a/src/java/main/gov/noaa/messageapi/operators/conditions/DoubleConditionOperator.java b/src/java/main/gov/noaa/messageapi/operators/conditions/DoubleConditionOperator.java index b90fb16377a1e22a4900a8a5fe0592b54d6b4e44..4fbba0bb584ef50016d929e65390babae813619c 100644 --- a/src/java/main/gov/noaa/messageapi/operators/conditions/DoubleConditionOperator.java +++ b/src/java/main/gov/noaa/messageapi/operators/conditions/DoubleConditionOperator.java @@ -3,7 +3,6 @@ package gov.noaa.messageapi.operators.conditions; import gov.noaa.messageapi.interfaces.IConditionOperator; import gov.noaa.messageapi.interfaces.IField; import gov.noaa.messageapi.interfaces.ICondition; -import gov.noaa.messageapi.operators.conditions.SimpleConditionOperator; /** * @author Ryan Berkheimer diff --git a/src/java/main/gov/noaa/messageapi/operators/conditions/FloatConditionOperator.java b/src/java/main/gov/noaa/messageapi/operators/conditions/FloatConditionOperator.java index d7178ae7859512366d812f66ae075a5af0b43735..936736b9bc152bd6f682e2acef805de75e2b73a1 100644 --- a/src/java/main/gov/noaa/messageapi/operators/conditions/FloatConditionOperator.java +++ b/src/java/main/gov/noaa/messageapi/operators/conditions/FloatConditionOperator.java @@ -3,7 +3,6 @@ package gov.noaa.messageapi.operators.conditions; import gov.noaa.messageapi.interfaces.IConditionOperator; import gov.noaa.messageapi.interfaces.IField; import gov.noaa.messageapi.interfaces.ICondition; -import gov.noaa.messageapi.operators.conditions.SimpleConditionOperator; /** * @author Ryan Berkheimer diff --git a/src/java/main/gov/noaa/messageapi/operators/conditions/IntegerConditionOperator.java b/src/java/main/gov/noaa/messageapi/operators/conditions/IntegerConditionOperator.java index 4dddb3a7e60acad669042c2890566782cdc208f0..1a9496d018413c825d959e0657328bdff2b12d78 100644 --- a/src/java/main/gov/noaa/messageapi/operators/conditions/IntegerConditionOperator.java +++ b/src/java/main/gov/noaa/messageapi/operators/conditions/IntegerConditionOperator.java @@ -3,7 +3,6 @@ package gov.noaa.messageapi.operators.conditions; import gov.noaa.messageapi.interfaces.IConditionOperator; import gov.noaa.messageapi.interfaces.IField; import gov.noaa.messageapi.interfaces.ICondition; -import gov.noaa.messageapi.operators.conditions.SimpleConditionOperator; /** * @author Ryan Berkheimer diff --git a/src/java/main/gov/noaa/messageapi/parsers/containers/TransformationFactoryParser.java b/src/java/main/gov/noaa/messageapi/parsers/containers/TransformationFactoryParser.java deleted file mode 100644 index 37a2195403a93360b7a5957fd5aa95292be3b77f..0000000000000000000000000000000000000000 --- a/src/java/main/gov/noaa/messageapi/parsers/containers/TransformationFactoryParser.java +++ /dev/null @@ -1,23 +0,0 @@ -package gov.noaa.messageapi.parsers.containers; - -import gov.noaa.messageapi.interfaces.ITransformationFactory; - -/** - * @author Ryan Berkheimer - */ -public class TransformationFactoryParser { - - public static ITransformationFactory build(String transformationClass) throws Exception { - try { - return (ITransformationFactory) constructPlugin(Class.forName(transformationClass)); - } catch (Exception e) { - System.err.println(String.format("Could not construct the TransformationFactory using the given class %s", transformationClass)); - return null; - } - } - - private static Object constructPlugin(Class pluginClass) throws Exception { - return pluginClass.getConstructor().newInstance(); - } - -} diff --git a/src/java/main/gov/noaa/messageapi/parsers/plugins/ContainerPluginParser.java b/src/java/main/gov/noaa/messageapi/parsers/plugins/ContainerPluginParser.java index 8df31092420eae1d968d7d550e00f2f443a892be..ea0a45097d2ec06a1ebbe080a52e805d09e64d50 100644 --- a/src/java/main/gov/noaa/messageapi/parsers/plugins/ContainerPluginParser.java +++ b/src/java/main/gov/noaa/messageapi/parsers/plugins/ContainerPluginParser.java @@ -5,7 +5,6 @@ import java.util.Set; import java.util.HashSet; import gov.noaa.messageapi.interfaces.IContainer; -import gov.noaa.messageapi.parsers.plugins.BasePluginParser; import gov.noaa.messageapi.interfaces.IPluginParser; /** @@ -29,7 +28,7 @@ public class ContainerPluginParser extends BasePluginParser implements IPluginPa protected Set getRequiredConstructorKeys() { Set set = new HashSet(); - set.add("metadata"); + //set.add("metadata"); set.add("collections"); return set; } diff --git a/src/java/main/gov/noaa/messageapi/parsers/plugins/ProtocolPluginParser.java b/src/java/main/gov/noaa/messageapi/parsers/plugins/ProtocolPluginParser.java index 1520533a6bd7e788a2e1129b13f1c4b3792c47c9..679bbf94bde22c71e85a22423b0041157a271bb9 100644 --- a/src/java/main/gov/noaa/messageapi/parsers/plugins/ProtocolPluginParser.java +++ b/src/java/main/gov/noaa/messageapi/parsers/plugins/ProtocolPluginParser.java @@ -7,8 +7,6 @@ import java.util.HashSet; import gov.noaa.messageapi.interfaces.IProtocol; import gov.noaa.messageapi.interfaces.IPluginParser; -import gov.noaa.messageapi.parsers.plugins.BasePluginParser; - /** * @author Ryan Berkheimer */ @@ -30,7 +28,7 @@ public class ProtocolPluginParser extends BasePluginParser implements IPluginPar protected Set getRequiredConstructorKeys() { Set set = new HashSet(); - set.add("metadata"); + //set.add("metadata"); set.add("endpoints"); return set; } diff --git a/src/java/main/gov/noaa/messageapi/parsers/plugins/SchemaPluginParser.java b/src/java/main/gov/noaa/messageapi/parsers/plugins/SchemaPluginParser.java index 68d3d14a0eb5790b0ae73fe177046e0108703e03..8fe22a57d4dab7c968455187fc4f22a67f22bc2f 100644 --- a/src/java/main/gov/noaa/messageapi/parsers/plugins/SchemaPluginParser.java +++ b/src/java/main/gov/noaa/messageapi/parsers/plugins/SchemaPluginParser.java @@ -6,7 +6,6 @@ import java.util.HashSet; import gov.noaa.messageapi.interfaces.ISchema; import gov.noaa.messageapi.interfaces.IPluginParser; -import gov.noaa.messageapi.parsers.plugins.BasePluginParser; /** * @author Ryan Berkheimer @@ -29,7 +28,7 @@ public class SchemaPluginParser extends BasePluginParser implements IPluginParse protected Set getRequiredConstructorKeys() { Set set = new HashSet(); - set.add("metadata"); + //set.add("metadata"); set.add("fields"); return set; } diff --git a/src/java/main/gov/noaa/messageapi/parsers/plugins/SessionPluginParser.java b/src/java/main/gov/noaa/messageapi/parsers/plugins/SessionPluginParser.java index 46535c0eb9e232366379bd34bbadaff337271872..bf448e86ddeb95bfb0dfb0849048cad009e8d425 100644 --- a/src/java/main/gov/noaa/messageapi/parsers/plugins/SessionPluginParser.java +++ b/src/java/main/gov/noaa/messageapi/parsers/plugins/SessionPluginParser.java @@ -11,11 +11,6 @@ import gov.noaa.messageapi.interfaces.ISchema; import gov.noaa.messageapi.interfaces.IPluginParser; -import gov.noaa.messageapi.parsers.plugins.BasePluginParser; -//import gov.noaa.messageapi.parsers.plugins.ContainerPluginParser; -//import gov.noaa.messageapi.parsers.plugins.ProtocolPluginParser; -//import gov.noaa.messageapi.parsers.plugins.SchemaPluginParser; - /** * @author Ryan Berkheimer */ diff --git a/src/java/main/gov/noaa/messageapi/protocols/DefaultProtocol.java b/src/java/main/gov/noaa/messageapi/protocols/DefaultProtocol.java index 290dffba4f5012a1952eaf3a29b0ce826a46ab12..dbaff5f8f18295d11d6e3a6dd03344bd1a419753 100644 --- a/src/java/main/gov/noaa/messageapi/protocols/DefaultProtocol.java +++ b/src/java/main/gov/noaa/messageapi/protocols/DefaultProtocol.java @@ -9,7 +9,6 @@ import gov.noaa.messageapi.interfaces.IContainer; import gov.noaa.messageapi.interfaces.IProtocol; import gov.noaa.messageapi.interfaces.IConnection; -import gov.noaa.messageapi.protocols.BaseProtocol; import gov.noaa.messageapi.metadata.DefaultMetadata; import gov.noaa.messageapi.connections.DefaultConnection; import gov.noaa.messageapi.definitions.ContainerDefinition; diff --git a/src/java/main/gov/noaa/messageapi/rejections/DefaultRejection.java b/src/java/main/gov/noaa/messageapi/rejections/DefaultRejection.java index 9dc047179262c9419584ac6297b390b54a8868ef..9aba2c33427c4158aa8a5b6aafc3a25fc9f7c516 100644 --- a/src/java/main/gov/noaa/messageapi/rejections/DefaultRejection.java +++ b/src/java/main/gov/noaa/messageapi/rejections/DefaultRejection.java @@ -4,8 +4,6 @@ import java.util.List; import gov.noaa.messageapi.interfaces.IRecord; import gov.noaa.messageapi.interfaces.IRejection; -import gov.noaa.messageapi.rejections.BaseRejection; - /** * @author Ryan Berkheimer diff --git a/src/java/main/gov/noaa/messageapi/requests/DefaultRequest.java b/src/java/main/gov/noaa/messageapi/requests/DefaultRequest.java index e0c150c481bf5a60a46dede687cf71d04f182ff1..6235776c59a6a8480d947ff31d88198513e0404f 100644 --- a/src/java/main/gov/noaa/messageapi/requests/DefaultRequest.java +++ b/src/java/main/gov/noaa/messageapi/requests/DefaultRequest.java @@ -8,7 +8,6 @@ import gov.noaa.messageapi.interfaces.IRequest; import gov.noaa.messageapi.interfaces.IResponse; import gov.noaa.messageapi.interfaces.IProtocol; -import gov.noaa.messageapi.requests.BaseRequest; import gov.noaa.messageapi.responses.DefaultResponse; diff --git a/src/java/main/gov/noaa/messageapi/responses/BaseResponse.java b/src/java/main/gov/noaa/messageapi/responses/BaseResponse.java index 9ad683d6fb33d59578c792df7b03df3b9c5be10e..359fe7d0d88211c9acaefc2ab61ee7e9b6359734 100644 --- a/src/java/main/gov/noaa/messageapi/responses/BaseResponse.java +++ b/src/java/main/gov/noaa/messageapi/responses/BaseResponse.java @@ -35,7 +35,7 @@ public class BaseResponse { return this.request; } - public Boolean isComplete() { + public boolean isComplete() { return this.complete; } @@ -47,7 +47,7 @@ public class BaseResponse { this.rejections = rejections; } - public void setComplete(Boolean complete) { + public void setComplete(boolean complete) { this.complete = complete; } diff --git a/src/java/main/gov/noaa/messageapi/responses/DefaultResponse.java b/src/java/main/gov/noaa/messageapi/responses/DefaultResponse.java index 362f0d290746a76a948c37737e736e8cea744816..2b59648cc0ddee83327b37b90cf6dde2e6cb4452 100644 --- a/src/java/main/gov/noaa/messageapi/responses/DefaultResponse.java +++ b/src/java/main/gov/noaa/messageapi/responses/DefaultResponse.java @@ -14,7 +14,6 @@ import gov.noaa.messageapi.interfaces.IPacket; import gov.noaa.messageapi.interfaces.IProtocolRecord; import gov.noaa.messageapi.interfaces.IContainerRecord; -import gov.noaa.messageapi.responses.BaseResponse; import gov.noaa.messageapi.requests.DefaultRequest; import gov.noaa.messageapi.utils.protocol.ConnectionUtils; diff --git a/src/java/main/gov/noaa/messageapi/schemas/DefaultSchema.java b/src/java/main/gov/noaa/messageapi/schemas/DefaultSchema.java index 13f88d60cbe234b4e1ff0c13ea6e571d73cee453..f6306d5d7e8b7ef51d41933de4a634507a2e2fea 100644 --- a/src/java/main/gov/noaa/messageapi/schemas/DefaultSchema.java +++ b/src/java/main/gov/noaa/messageapi/schemas/DefaultSchema.java @@ -8,7 +8,6 @@ import gov.noaa.messageapi.interfaces.ISchema; import gov.noaa.messageapi.interfaces.IRecord; import gov.noaa.messageapi.interfaces.IConditionOperator; -import gov.noaa.messageapi.schemas.BaseSchema; import gov.noaa.messageapi.metadata.DefaultMetadata; import gov.noaa.messageapi.records.schema.SchemaRecord; diff --git a/src/java/main/gov/noaa/messageapi/sessions/DefaultSession.java b/src/java/main/gov/noaa/messageapi/sessions/DefaultSession.java index 070b7c0a3b6d19ed3a5fafcebc74a86f4084e552..9890d764f52c9b48e995420d0a0d2d16bd6d51f0 100644 --- a/src/java/main/gov/noaa/messageapi/sessions/DefaultSession.java +++ b/src/java/main/gov/noaa/messageapi/sessions/DefaultSession.java @@ -6,7 +6,6 @@ import gov.noaa.messageapi.interfaces.IProtocol; import gov.noaa.messageapi.interfaces.IContainer; import gov.noaa.messageapi.interfaces.IRequest; -import gov.noaa.messageapi.sessions.BaseSession; import gov.noaa.messageapi.requests.DefaultRequest; /** diff --git a/src/java/main/gov/noaa/messageapi/transformations/BaseTransformation.java b/src/java/main/gov/noaa/messageapi/transformations/BaseTransformation.java new file mode 100644 index 0000000000000000000000000000000000000000..d495015fd39df4436fb0c7f3cd3345857281a9d4 --- /dev/null +++ b/src/java/main/gov/noaa/messageapi/transformations/BaseTransformation.java @@ -0,0 +1,26 @@ +package gov.noaa.messageapi.transformations; + +import java.util.Map; + +/** + * The abstract base class for user transformations. This class provides extending user + * endpoints the convenience of parsing and provides all possible generic default methods. + * @author Ryan Berkheimer + */ +public abstract class BaseTransformation { + + public Map constructorMap = null; + + public BaseTransformation(Map parameters) { + this.setConstructor(parameters); + } + + public Map getConstructor() { + return this.constructorMap; + } + + private void setConstructor(Map constructorMap) { + this.constructorMap = constructorMap; + } + +} \ No newline at end of file diff --git a/src/java/main/gov/noaa/messageapi/transformations/NativeTransformation.java b/src/java/main/gov/noaa/messageapi/transformations/NativeTransformation.java new file mode 100644 index 0000000000000000000000000000000000000000..ad93cdc34233c925a21530468dd9e27e32a35ae9 --- /dev/null +++ b/src/java/main/gov/noaa/messageapi/transformations/NativeTransformation.java @@ -0,0 +1,54 @@ +package gov.noaa.messageapi.transformations; + +import java.util.Map; +import java.util.List; + +import gov.noaa.messageapi.interfaces.ITransformation; +import gov.noaa.messageapi.interfaces.IRecord; + +/** + *

NativeTransformation

This is a wrapper class for transformations that call into + * native code held as binary libs through the JNI (Java Native + * Interface). + *

+ * This transformation is designed so that native code doesn't have to provide an + * additional Java wrapper. The native library code will have to be built + * with a C wrapper that imports the Transformation.h header. A guide for building these + * native libraries can be seen in the examples, and is facilitated by the use of the + * provided makefile templates. + *

+ * To make use of this transformation, users are asked to configure 1 + * property in the manifest: + *

+ * native-library(required, string) - corresponds to a fully + * qualified path pointing to the native library binary. This is usually a .so, + * .dll, or .jnilib, depending on operating system. + *

+ * + * @author Ryan Berkheimer + */ +public class NativeTransformation extends BaseTransformation implements ITransformation { + + private native List process(long nativeInstance); + private synchronized native long create(Map> recordMap); + private synchronized native void release(long instanceId); + + public NativeTransformation(Map params) { + super(params); + this.loadNativeLib((String)params.get("native-library")); + } + + public void loadNativeLib(String nativeLibrary) { + try { + System.load(nativeLibrary); + } catch (Exception e) {} + } + + public List process(Map> recordMap) { + long nativeInstance = this.create(recordMap); + List transformedRecords = this.process(nativeInstance); + this.release(nativeInstance); + return transformedRecords; + } + +} \ No newline at end of file diff --git a/src/java/main/gov/noaa/messageapi/transformations/joins/StringFieldJoin.java b/src/java/main/gov/noaa/messageapi/transformations/joins/StringFieldJoin.java index adc48bb320a79eeb013677583256b1c7d965e41b..363f5632992a2badcbac5826ecded622ac6ceb90 100644 --- a/src/java/main/gov/noaa/messageapi/transformations/joins/StringFieldJoin.java +++ b/src/java/main/gov/noaa/messageapi/transformations/joins/StringFieldJoin.java @@ -11,6 +11,7 @@ import gov.noaa.messageapi.interfaces.ITransformation; import gov.noaa.messageapi.fields.DefaultField; import gov.noaa.messageapi.records.schema.SchemaRecord; +import gov.noaa.messageapi.transformations.BaseTransformation; /** @@ -59,12 +60,13 @@ import gov.noaa.messageapi.records.schema.SchemaRecord; *

* @author Ryan Berkheimer */ -public class StringFieldJoin implements ITransformation { +public class StringFieldJoin extends BaseTransformation implements ITransformation { private IField joinField = null; private IField collectionField = null; - public StringFieldJoin(List fields, Map params) { + public StringFieldJoin(Map params) { + super(params); this.setJoinField((String) params.get("join-field")); this.setCollectionField((String) params.get("collection-field")); } diff --git a/src/java/main/gov/noaa/messageapi/transformations/reductions/ReduceTransformation.java b/src/java/main/gov/noaa/messageapi/transformations/reductions/ReduceTransformation.java index 12cd71db07fc41604e3ee769e041d66e2b915811..a45f3124288205a96d8b9555be835060c62ab57a 100644 --- a/src/java/main/gov/noaa/messageapi/transformations/reductions/ReduceTransformation.java +++ b/src/java/main/gov/noaa/messageapi/transformations/reductions/ReduceTransformation.java @@ -6,13 +6,17 @@ import java.util.List; import gov.noaa.messageapi.interfaces.IRecord; import gov.noaa.messageapi.interfaces.ITransformation; +import gov.noaa.messageapi.transformations.BaseTransformation; + /** * @author Ryan Berkheimer */ -public class ReduceTransformation implements ITransformation { +public class ReduceTransformation extends BaseTransformation implements ITransformation { - public ReduceTransformation(List fields, Map params) {} + public ReduceTransformation(Map params) { + super(params); + } public List process(Map> transformationMap) { return transformationMap.get("reduce-list"); diff --git a/src/java/main/gov/noaa/messageapi/utils/general/PathUtils.java b/src/java/main/gov/noaa/messageapi/utils/general/PathUtils.java index f6ab5b4fd9401c89c1dfefd0a8d49692e36b28e4..bf1116fa0dcc62d218beaf0f2dcd401c973ade13 100644 --- a/src/java/main/gov/noaa/messageapi/utils/general/PathUtils.java +++ b/src/java/main/gov/noaa/messageapi/utils/general/PathUtils.java @@ -4,25 +4,12 @@ import java.io.File; import java.util.List; import java.util.ArrayList; -//import gov.noaa.messageapi.utils.general.EnvUtils; - /** * @author Ryan Berkheimer */ public class PathUtils { - private static String replaceLast(String string, String toReplace, String replacement) { - int pos = string.lastIndexOf(toReplace); - if (pos > -1) { - return string.substring(0, pos) - + replacement - + string.substring(pos + toReplace.length(), string.length()); - } else { - return string; - } - } - /** * This method expands the {} special character found in strings that are read during parsing. * This method is not durable but it works on current OSX Darwin and both Redhat and Ubuntu Linuxes. @@ -42,18 +29,18 @@ public class PathUtils { String returnPath; switch (EnvUtils.getOS()) { case "osx": - replaceTest = replaceLast(jarDir.getAbsolutePath(), "/classes/java/test", ""); - replaceMain = replaceLast(replaceTest, "/classes/java/main", ""); + replaceTest = StringUtils.replaceLast(jarDir.getAbsolutePath(), "/classes/java/test", ""); + replaceMain = StringUtils.replaceLast(replaceTest, "/classes/java/main", ""); returnPath = path.replace("{}", replaceMain); return returnPath; case "unix": - replaceTest = replaceLast(jarDir.getAbsolutePath(), "/classes/java/test", ""); - replaceMain = replaceLast(replaceTest, "/classes/java/main", ""); + replaceTest = StringUtils.replaceLast(jarDir.getAbsolutePath(), "/classes/java/test", ""); + replaceMain = StringUtils.replaceLast(replaceTest, "/classes/java/main", ""); returnPath = path.replace("{}", replaceMain); return returnPath; default: - replaceTest = replaceLast(jarDir.getAbsolutePath(), "/classes/java/test", ""); - replaceMain = replaceLast(replaceTest, "/classes/java/main", ""); + replaceTest = StringUtils.replaceLast(jarDir.getAbsolutePath(), "/classes/java/test", ""); + replaceMain = StringUtils.replaceLast(replaceTest, "/classes/java/main", ""); returnPath = path.replace("{}", replaceMain); return returnPath; } @@ -62,6 +49,34 @@ public class PathUtils { } } + public static String reconcileKeywords(String path, String keyword) { + if (path.contains(keyword)) { + File jarDir = new File(ClassLoader.getSystemClassLoader().getResource(".").getPath()); + String replaceTest; + String replaceMain; + String returnPath; + switch (EnvUtils.getOS()) { + case "osx": + replaceTest = StringUtils.replaceLast(jarDir.getAbsolutePath(), "/classes/java/test", ""); + replaceMain = StringUtils.replaceLast(replaceTest, "/classes/java/main", ""); + returnPath = path.replace(keyword, replaceMain); + return returnPath; + case "unix": + replaceTest = StringUtils.replaceLast(jarDir.getAbsolutePath(), "/classes/java/test", ""); + replaceMain = StringUtils.replaceLast(replaceTest, "/classes/java/main", ""); + returnPath = path.replace(keyword, replaceMain); + return returnPath; + default: + replaceTest = StringUtils.replaceLast(jarDir.getAbsolutePath(), "/classes/java/test", ""); + replaceMain = StringUtils.replaceLast(replaceTest, "/classes/java/main", ""); + returnPath = path.replace(keyword, replaceMain); + return returnPath; + } + } else { + return path; + } + } + public static List reconcileKeywords(List paths) { List l = new ArrayList(); for (String path: paths) { diff --git a/src/java/main/gov/noaa/messageapi/utils/general/StringUtils.java b/src/java/main/gov/noaa/messageapi/utils/general/StringUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..f5cf6e65ba4be616571ae204dbc7765cd1238929 --- /dev/null +++ b/src/java/main/gov/noaa/messageapi/utils/general/StringUtils.java @@ -0,0 +1,24 @@ +package gov.noaa.messageapi.utils.general; + + +/** + * @author Ryan Berkheimer + */ +public class StringUtils { + + /** + * Replaces the last occurance of the specified target substring with the specified replacement substring + * within the specified string. If there is no occurance, just returns the original string. + */ + public static String replaceLast(String string, String toReplace, String replacement) { + int pos = string.lastIndexOf(toReplace); + if (pos > -1) { + return string.substring(0, pos) + + replacement + + string.substring(pos + toReplace.length(), string.length()); + } else { + return string; + } + } + +} diff --git a/src/java/main/gov/noaa/messageapi/utils/protocol/ConnectionUtils.java b/src/java/main/gov/noaa/messageapi/utils/protocol/ConnectionUtils.java index c0d1323db56036790d85a8c99c5be50674e06b02..28e8f97cf1e30c89fb829c58512e1acc9d67cd15 100644 --- a/src/java/main/gov/noaa/messageapi/utils/protocol/ConnectionUtils.java +++ b/src/java/main/gov/noaa/messageapi/utils/protocol/ConnectionUtils.java @@ -4,14 +4,15 @@ import java.util.Map; import java.util.List; import java.util.Optional; import java.util.HashMap; +import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.stream.Collectors; import java.util.concurrent.CompletableFuture; import gov.noaa.messageapi.interfaces.IConnection; import gov.noaa.messageapi.interfaces.IProtocolRecord; +import gov.noaa.messageapi.interfaces.ITransformation; import gov.noaa.messageapi.interfaces.IPacket; -import gov.noaa.messageapi.interfaces.ITransformationFactory; import gov.noaa.messageapi.utils.general.ListUtils; import gov.noaa.messageapi.utils.general.MapUtils; @@ -103,14 +104,26 @@ public class ConnectionUtils { return returnMap; } + public static ITransformation getTransformationInstance(String transformationClass, Map args) { + try { + Class pluginClass = Class.forName(transformationClass); + Class[] ctrClasses = { Map.class }; + Constructor constructor = pluginClass.getDeclaredConstructor(ctrClasses); + return (ITransformation) constructor.newInstance(args); + } catch (Exception e){ + System.out.println(String.format("Could not build a transformation instance for %s", transformationClass)); + return null; + } + } + @SuppressWarnings("unchecked") - public static Map> buildTransformationMap(List ids, List> allMaps, ITransformationFactory factory) { + public static Map> buildTransformationMap(List ids, List> allMaps) { List> idMaps = allMaps.stream().filter(m -> ids.contains((String)m.get("id"))).collect(Collectors.toList()); List>> tMaps = idMaps.stream().map(m -> { Map> templateMap = new HashMap>(); Map valMap = new HashMap(); - valMap.put("instance", factory.getTransformation((String)m.get("operator"), (List)m.get("fields"), (Map)m.get("constructor"))); + valMap.put("instance", ConnectionUtils.getTransformationInstance((String)m.get("operator"), (Map)m.get("constructor"))); valMap.put("parameters", ConnectionUtils.makeRecordSymbolMaps((Map)m.get("records"))); templateMap.put((String)m.get("id"), valMap); return templateMap; diff --git a/src/java/main/gov/noaa/messageapi/utils/request/PacketUtils.java b/src/java/main/gov/noaa/messageapi/utils/request/PacketUtils.java index f53d4d9a514634f62b37590b19a78861bb7c93dc..d8109167bd377be9050ffa4ed17db816631c90de 100644 --- a/src/java/main/gov/noaa/messageapi/utils/request/PacketUtils.java +++ b/src/java/main/gov/noaa/messageapi/utils/request/PacketUtils.java @@ -27,8 +27,7 @@ public class PacketUtils { List primaryRejections = RejectionUtils.getRequiredFieldRejections(records); List filteredRecords = SchemaUtils.filterFieldlessConditions( SchemaUtils.filterNonValuedConditions( - SchemaUtils.filterNonValuedFields( - SchemaUtils.filterRejections(records, primaryRejections)))); + SchemaUtils.filterRejections(records, primaryRejections))); List secondaryRejections = RejectionUtils.getFieldConditionRejections(schema, filteredRecords); dataPacket.setRecords(SchemaUtils.filterRejections(filteredRecords, secondaryRejections)); dataPacket.setRejections(ListUtils.flatten(new ArrayList>(Arrays.asList(primaryRejections, secondaryRejections)))); diff --git a/src/java/main/gov/noaa/messageapi/utils/request/SchemaUtils.java b/src/java/main/gov/noaa/messageapi/utils/request/SchemaUtils.java index 3bde2ef47f8bdb538e135ef0d687c0eae919a4e9..c46c59f315804b615354f8645aea7e4d42726411 100644 --- a/src/java/main/gov/noaa/messageapi/utils/request/SchemaUtils.java +++ b/src/java/main/gov/noaa/messageapi/utils/request/SchemaUtils.java @@ -63,9 +63,11 @@ public class SchemaUtils { public static List filterNonValuedConditions(List records) { return records.stream().map(r -> { List conditions = ConditionUtils.filterNonValuedConditions(r.getConditions()); - IRecord newR = r.getCopy(); - newR.setConditions(conditions); - return newR; + //IRecord newR = r.getCopy(); + //newR.setConditions(conditions); + r.setConditions(conditions); + //return newR; + return r; }).collect(Collectors.toList()); } diff --git a/src/java/main/gov/noaa/messageapi/utils/schema/FieldUtils.java b/src/java/main/gov/noaa/messageapi/utils/schema/FieldUtils.java index 48b8d9ac022e8a0b6420d19165cd2219b528c88c..f31ec1ace2991630507be76c653b38a588e66a08 100644 --- a/src/java/main/gov/noaa/messageapi/utils/schema/FieldUtils.java +++ b/src/java/main/gov/noaa/messageapi/utils/schema/FieldUtils.java @@ -15,7 +15,6 @@ import gov.noaa.messageapi.interfaces.IComparisonCondition; import gov.noaa.messageapi.rejections.DefaultRejection; import gov.noaa.messageapi.utils.general.ListUtils; -//import gov.noaa.messageapi.utils.schema.ConditionUtils; /** * This static utility class holds generic and immutable methods related to diff --git a/src/java/test/gov/noaa/messageapi/test/factories/transformations/FileReaderFactory.java b/src/java/test/gov/noaa/messageapi/test/factories/transformations/FileReaderFactory.java deleted file mode 100644 index 146224ffa4dec7ef17f918b65844e9242e308f93..0000000000000000000000000000000000000000 --- a/src/java/test/gov/noaa/messageapi/test/factories/transformations/FileReaderFactory.java +++ /dev/null @@ -1,29 +0,0 @@ -package gov.noaa.messageapi.test.factories.transformations; - -import java.util.Map; -import java.util.List; - -import gov.noaa.messageapi.interfaces.ITransformation; -import gov.noaa.messageapi.interfaces.ITransformationFactory; -import gov.noaa.messageapi.test.transformations.FixRelativePathsTransformation; - -/** - * @author Ryan Berkheimer - */ -public class FileReaderFactory implements ITransformationFactory { - - /** - * Returns an operator based on a data type name as a string. - * @param type The type of operator to return - * @return A new operator based on the specified type - */ - public ITransformation getTransformation(String type, List fields, Map params) { - switch (type) { - case "fix-relative-paths": - return new FixRelativePathsTransformation(fields, params); - default: - return null; - } - } - -} diff --git a/src/java/test/gov/noaa/messageapi/test/transformations/FixRelativePathsTransformation.java b/src/java/test/gov/noaa/messageapi/test/transformations/FixRelativePathsTransformation.java index 42bdab28b4d87060ca9aa4bf4361ccb1f9ba1949..d811394bbcac50b9daf9964b1486a75940bb1b6d 100644 --- a/src/java/test/gov/noaa/messageapi/test/transformations/FixRelativePathsTransformation.java +++ b/src/java/test/gov/noaa/messageapi/test/transformations/FixRelativePathsTransformation.java @@ -9,36 +9,89 @@ import gov.noaa.messageapi.interfaces.ITransformation; import gov.noaa.messageapi.utils.general.ListUtils; import gov.noaa.messageapi.utils.general.PathUtils; +import gov.noaa.messageapi.utils.general.StringUtils; + +import gov.noaa.messageapi.transformations.BaseTransformation; /** - *

FixRelativePathsTransformation

+ *

FixRelativePathsTransformation

Description: + *

+ * This Transformation will return a list of records for every record in the + * transform-key container. The new list of records will have any paths + * specified in the fields set for this transformation updated with the + * relative path keyword (defaults to '{}') replaced with a different string + * (options described below). By default, the keyword is replaced by the root + * path of where the code is being executed (so, if in a JAR, the root of the + * JAR.) + *

+ *

+ *

Configuration Parameters

transform-key(required) (String): + * The name of the transformation-container containing records having fields + * that have relative paths to be transformed. For example, if a transformation + * has a specified container "records": {"file-collection": {"COLLECTION": + * "coll-1"}}, the "file-collection" container record set could be specified. + *

+ * fields (required) (List(String)): A list of strings that specify + * container fields to be transformed. E.g., using the example container above, + * if coll-1 had fields with paths desired to be expanded called "dir-path-1" + * and "dir-path-2", then this parameter would be specified as "fields": + * ["dir-path-1", "dir-path-2"] + *

+ * substitution-keyword (optional) (String): A substring that will be substituted in the field value. + * Defaults to {}. *

- * This Transformation will return a list of - * records for every record in the transform-key container. The new list - * of records will have any paths specified in the fields set for this - * transformation updated with the relative path keyword ({}) replaced with the - * package path. This transformation is useful in file operation tests or using - * package-internal/relative resources. *

- * Note - this uses a string method, so fields must be string-castable. + * substitution-string (optional) (String): A substring that will replace the keyword. If not specified, + * defaults to package root of running resource. + *

+ *

+ * substitution-field (optional) (String): A field that has a value that will be used in substitution. + * If not specified, defaults to package root of running resource. + *

+ * + * Note - this uses a string method, so fields (specified above) must be + * string-castable. + *

+ * Note - if both substitution-string and substitution-field are specified, the substitution-string takes precedence. * * @author Ryan Berkheimer */ -public class FixRelativePathsTransformation implements ITransformation { +public class FixRelativePathsTransformation extends BaseTransformation implements ITransformation { private List relativePathFields = null; private String transformKey = null; + private String substitutionKeyword = "{}"; + private String substitutionString = null; + private String substitutionField = null; - public FixRelativePathsTransformation(List fields, Map params) { - this.setRelativePathFields(fields); - this.setTransformKey((String) params.get("transform-key")); + @SuppressWarnings("unchecked") + public FixRelativePathsTransformation(Map params) { + super(params); + try { + this.setRelativePathFields((List) params.get("fields")); + this.setTransformKey((String) params.get("transform-key")); + } catch (Exception e) { + System.err.println("Fix Relative Paths Transformation is missing a required field. Check your params map."); + System.exit(1); + } + this.setSubstitutionKeyword(params); + this.setSubstitutionString(params); + this.setSubstitutionField(params); } public List process(Map> transformationMap) { return ListUtils.removeAllNulls(transformationMap.get(this.getTransformKey()).stream().map(record -> { this.getRelativePathFields().stream().forEach(field -> { - record.setField(field, PathUtils.reconcileKeywords((String) record.getField(field).getValue())); + if (this.getSubstitutionString() != null) { + record.setField(field, StringUtils.replaceLast((String) record.getField(field).getValue(), this.getSubstitutionKeyword(), + this.getSubstitutionString())); + } else if (this.getSubstitutionField() != null) { + record.setField(field, StringUtils.replaceLast((String) record.getField(field).getValue(), this.getSubstitutionKeyword(), + this.getSubstitutionField())); + } else { + record.setField(field, PathUtils.reconcileKeywords((String) record.getField(field).getValue(), this.getSubstitutionKeyword())); + } }); return record; }).collect(Collectors.toList())); @@ -56,8 +109,38 @@ public class FixRelativePathsTransformation implements ITransformation { this.transformKey = transformKey; } + private void setSubstitutionKeyword(Map parameters) { + if (parameters.containsKey("substitution-keyword")) { + this.substitutionKeyword = (String) parameters.get("substitution-keyword"); + } + } + + private void setSubstitutionString(Map parameters) { + if (parameters.containsKey("substitution-string")) { + this.substitutionString = (String) parameters.get("substitution-string"); + } + } + + private void setSubstitutionField(Map parameters) { + if (parameters.containsKey("substitution-field")) { + this.substitutionField = (String) parameters.get("substitution-field"); + } + } + private String getTransformKey() { return this.transformKey; } + private String getSubstitutionKeyword() { + return this.substitutionKeyword; + } + + private String getSubstitutionString() { + return this.substitutionString; + } + + private String getSubstitutionField() { + return this.substitutionField; + } + }