turcsanyip commented on a change in pull request #4510:
URL: https://github.com/apache/nifi/pull/4510#discussion_r508028622



##########
File path: 
nifi-nar-bundles/nifi-hazelcast-bundle/nifi-hazelcast-services/src/main/resources/docs/org.apache.nifi.hazelcast.services.cachemanager.EmbeddedHazelcastCacheManager/additionalDetails.html
##########
@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+<html lang="en">
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+      http://www.apache.org/licenses/LICENSE-2.0
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<head>
+    <meta charset="utf-8" />
+    <title>EmbeddedHazelcastCacheManager</title>
+    <link rel="stylesheet" href="/nifi-docs/css/component-usage.css" 
type="text/css" />
+</head>
+
+<>

Review comment:
       Typo: `<body>`

##########
File path: 
nifi-nar-bundles/nifi-hazelcast-bundle/nifi-hazelcast-services/src/main/java/org/apache/nifi/hazelcast/services/cachemanager/EmbeddedHazelcastCacheManager.java
##########
@@ -0,0 +1,244 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hazelcast.services.cachemanager;
+
+import com.hazelcast.config.Config;
+import com.hazelcast.config.NetworkConfig;
+import com.hazelcast.config.TcpIpConfig;
+import com.hazelcast.core.Hazelcast;
+import com.hazelcast.core.HazelcastInstance;
+import org.apache.nifi.annotation.documentation.CapabilityDescription;
+import org.apache.nifi.annotation.documentation.Tags;
+import org.apache.nifi.components.AllowableValue;
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.components.ValidationContext;
+import org.apache.nifi.components.ValidationResult;
+import org.apache.nifi.context.PropertyContext;
+import org.apache.nifi.controller.ConfigurationContext;
+import org.apache.nifi.expression.ExpressionLanguageScope;
+import org.apache.nifi.processor.exception.ProcessException;
+import org.apache.nifi.processor.util.StandardValidators;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+@Tags({"hazelcast", "cache"})
+@CapabilityDescription("A service that provides connections to an embedded 
Hazelcast instance started by NiFi." +
+        " The server does not ask for authentication, it is recommended to run 
it within secured network.")
+public class EmbeddedHazelcastCacheManager extends 
IMapBasedHazelcastCacheManager {
+
+    private static final int DEFAULT_HAZELCAST_PORT = 5701;
+    private static final String PORT_SEPARATOR = ":";
+    private static final String INSTANCE_CREATION_LOG = "Embedded Hazelcast 
server instance with instance name %s has been created successfully";
+    private static final String MEMBER_LIST_LOG = "Hazelcast cluster will be 
created based on the NiFi cluster with the following members: %s";
+
+    private static final AllowableValue HA_NONE = new AllowableValue("none", 
"None", "No high availability or data replication is provided," +
+            " every node has access only to the data stored locally.");
+    private static final AllowableValue HA_CLUSTER = new 
AllowableValue("cluster", "Cluster", "Creates Hazelcast cluster based on the 
NiFi cluster:" +
+            " It expects every NiFi nodes to have a running Hazelcast instance 
on the same port as specified in the Hazelcast Port property. No explicit 
listing of the" +
+            " instances is needed.");
+    private static final AllowableValue HA_EXPLICIT = new 
AllowableValue("explicit", "Explicit", "Works with an explicit list of 
Hazelcast instances," +
+            " creating a cluster using the listed instances. This provides 
greater control, making it possible to utilize only certain nodes as Hazelcast 
servers." +
+            " The list of Hazelcast instances can be set in the property 
\"Hazelcast Instances\". The list items must refer to hosts within the NiFi 
cluster, no external Hazelcast" +
+            " is allowed. NiFi nodes are not listed will be join to the 
Hazelcast cluster as clients.");
+
+    private static final PropertyDescriptor HAZELCAST_PORT = new 
PropertyDescriptor.Builder()
+            .name("hazelcast-port")
+            .displayName("Hazelcast Port")
+            .description("Port for the Hazelcast instance to use. If not 
specified, the default value will be used, which is " + DEFAULT_HAZELCAST_PORT 
+ ".")

Review comment:
       The "If not specified..." part is a generic statement which is true for 
all required properties having a default value.
   I would rather omit that sentence.

##########
File path: 
nifi-nar-bundles/nifi-hazelcast-bundle/nifi-hazelcast-services/src/main/java/org/apache/nifi/hazelcast/services/cachemanager/EmbeddedHazelcastCacheManager.java
##########
@@ -0,0 +1,244 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hazelcast.services.cachemanager;
+
+import com.hazelcast.config.Config;
+import com.hazelcast.config.NetworkConfig;
+import com.hazelcast.config.TcpIpConfig;
+import com.hazelcast.core.Hazelcast;
+import com.hazelcast.core.HazelcastInstance;
+import org.apache.nifi.annotation.documentation.CapabilityDescription;
+import org.apache.nifi.annotation.documentation.Tags;
+import org.apache.nifi.components.AllowableValue;
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.components.ValidationContext;
+import org.apache.nifi.components.ValidationResult;
+import org.apache.nifi.context.PropertyContext;
+import org.apache.nifi.controller.ConfigurationContext;
+import org.apache.nifi.expression.ExpressionLanguageScope;
+import org.apache.nifi.processor.exception.ProcessException;
+import org.apache.nifi.processor.util.StandardValidators;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+@Tags({"hazelcast", "cache"})
+@CapabilityDescription("A service that provides connections to an embedded 
Hazelcast instance started by NiFi." +

Review comment:
       I would mention here that this CS not only provides connections to the 
embedded Hazelcast but it actually runs the embedded server. Something like 
this (also similar to the comment of StandaloneHazelcastCacheManager):
   "A service that runs embedded Hazelcast and provides cache instances backed 
by that."

##########
File path: 
nifi-nar-bundles/nifi-hazelcast-bundle/nifi-hazelcast-services/src/main/java/org/apache/nifi/hazelcast/services/cachemanager/EmbeddedHazelcastCacheManager.java
##########
@@ -0,0 +1,244 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hazelcast.services.cachemanager;
+
+import com.hazelcast.config.Config;
+import com.hazelcast.config.NetworkConfig;
+import com.hazelcast.config.TcpIpConfig;
+import com.hazelcast.core.Hazelcast;
+import com.hazelcast.core.HazelcastInstance;
+import org.apache.nifi.annotation.documentation.CapabilityDescription;
+import org.apache.nifi.annotation.documentation.Tags;
+import org.apache.nifi.components.AllowableValue;
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.components.ValidationContext;
+import org.apache.nifi.components.ValidationResult;
+import org.apache.nifi.context.PropertyContext;
+import org.apache.nifi.controller.ConfigurationContext;
+import org.apache.nifi.expression.ExpressionLanguageScope;
+import org.apache.nifi.processor.exception.ProcessException;
+import org.apache.nifi.processor.util.StandardValidators;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+@Tags({"hazelcast", "cache"})
+@CapabilityDescription("A service that provides connections to an embedded 
Hazelcast instance started by NiFi." +
+        " The server does not ask for authentication, it is recommended to run 
it within secured network.")
+public class EmbeddedHazelcastCacheManager extends 
IMapBasedHazelcastCacheManager {
+
+    private static final int DEFAULT_HAZELCAST_PORT = 5701;
+    private static final String PORT_SEPARATOR = ":";
+    private static final String INSTANCE_CREATION_LOG = "Embedded Hazelcast 
server instance with instance name %s has been created successfully";
+    private static final String MEMBER_LIST_LOG = "Hazelcast cluster will be 
created based on the NiFi cluster with the following members: %s";
+
+    private static final AllowableValue HA_NONE = new AllowableValue("none", 
"None", "No high availability or data replication is provided," +
+            " every node has access only to the data stored locally.");
+    private static final AllowableValue HA_CLUSTER = new 
AllowableValue("cluster", "Cluster", "Creates Hazelcast cluster based on the 
NiFi cluster:" +
+            " It expects every NiFi nodes to have a running Hazelcast instance 
on the same port as specified in the Hazelcast Port property. No explicit 
listing of the" +
+            " instances is needed.");
+    private static final AllowableValue HA_EXPLICIT = new 
AllowableValue("explicit", "Explicit", "Works with an explicit list of 
Hazelcast instances," +
+            " creating a cluster using the listed instances. This provides 
greater control, making it possible to utilize only certain nodes as Hazelcast 
servers." +
+            " The list of Hazelcast instances can be set in the property 
\"Hazelcast Instances\". The list items must refer to hosts within the NiFi 
cluster, no external Hazelcast" +
+            " is allowed. NiFi nodes are not listed will be join to the 
Hazelcast cluster as clients.");
+
+    private static final PropertyDescriptor HAZELCAST_PORT = new 
PropertyDescriptor.Builder()
+            .name("hazelcast-port")
+            .displayName("Hazelcast Port")
+            .description("Port for the Hazelcast instance to use. If not 
specified, the default value will be used, which is " + DEFAULT_HAZELCAST_PORT 
+ ".")
+            .required(true)
+            .defaultValue(String.valueOf(DEFAULT_HAZELCAST_PORT))
+            .addValidator(StandardValidators.PORT_VALIDATOR)
+            
.expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
+            .build();
+
+    private static final PropertyDescriptor HAZELCAST_HA_MODE = new 
PropertyDescriptor.Builder()
+            .name("hazelcast-ha-mode")
+            .displayName("Hazelcast High Availability Mode")
+            .description("Specifies with what strategy the Hazelcast cluster 
should be created.")
+            .required(true)
+            .allowableValues(HA_NONE, HA_CLUSTER, HA_EXPLICIT)
+            .defaultValue(HA_NONE.getValue()) // None is used for default in 
order to be valid with standalone NiFi.
+            .build();
+
+    private static final PropertyDescriptor HAZELCAST_INSTANCES = new 
PropertyDescriptor.Builder()
+            .name("hazelcast-instances")
+            .displayName("Hazelcast Instances")
+            .description("Only used when high availability mode is set to 
\"Explicit\"!" +
+                    " List of NiFi instance host names which should be part of 
the Hazelcast cluster. Host names are separated by comma." +
+                    " The port specified in the \"Hazelcast Port\" property 
will be used as server port." +
+                    " The list must contain every instances that will be part 
of the cluster. Other instances will join the Hazelcast cluster as client.")

Review comment:
       Not perfectly sure, but the following would be correct:
   - "every instance"
   - "as clients"

##########
File path: 
nifi-nar-bundles/nifi-hazelcast-bundle/nifi-hazelcast-services/src/main/resources/docs/org.apache.nifi.hazelcast.services.cachemanager.StandaloneHazelcastCacheManager/additionalDetails.html
##########
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html lang="en">
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+      http://www.apache.org/licenses/LICENSE-2.0
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<head>
+    <meta charset="utf-8" />
+    <title>StandaloneHazelcastCacheManager</title>
+    <link rel="stylesheet" href="/nifi-docs/css/component-usage.css" 
type="text/css" />
+</head>
+
+<body>
+<h2>StandaloneHazelcastCacheManager</h2>
+
+<p>
+    This service connects to one or more existing Hazelcast instances as 
client. Hazelcast 4.0.0 or newer version is required.

Review comment:
       Suggestion: "This service connects to an external Hazelcast cluster (or 
standalone instance) as client."
   
   The client always connects to the whole Hazelcast cluster (if it is 
clustered) and not to specific nodes (even if only a few nodes were listed as 
the initial/join nodes). That's why I would avoid the "one or more instances".

##########
File path: 
nifi-nar-bundles/nifi-hazelcast-bundle/nifi-hazelcast-services/src/main/java/org/apache/nifi/hazelcast/services/cacheclient/HazelcastMapCacheClient.java
##########
@@ -0,0 +1,254 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hazelcast.services.cacheclient;
+
+import org.apache.nifi.annotation.documentation.CapabilityDescription;
+import org.apache.nifi.annotation.documentation.Tags;
+import org.apache.nifi.annotation.lifecycle.OnDisabled;
+import org.apache.nifi.annotation.lifecycle.OnEnabled;
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.controller.AbstractControllerService;
+import org.apache.nifi.controller.ConfigurationContext;
+import org.apache.nifi.distributed.cache.client.AtomicCacheEntry;
+import 
org.apache.nifi.distributed.cache.client.AtomicDistributedMapCacheClient;
+import org.apache.nifi.distributed.cache.client.Deserializer;
+import org.apache.nifi.distributed.cache.client.Serializer;
+import org.apache.nifi.expression.ExpressionLanguageScope;
+import org.apache.nifi.hazelcast.services.cache.HazelcastCache;
+import org.apache.nifi.hazelcast.services.cachemanager.HazelcastCacheManager;
+import org.apache.nifi.hazelcast.services.util.LongUtil;
+import org.apache.nifi.processor.util.StandardValidators;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+import java.util.regex.Pattern;
+
+/**
+ * An implementation of DistributedMapCacheClient that uses Hazelcast as the 
backing cache.
+ *
+ * Note: By design, the client should not directly depend on Hazelcast 
specific classes to allow easy version and implementation changes.
+ */
+@Tags({ "hazelcast", "cache", "map"})
+@CapabilityDescription("An implementation of DistributedMapCacheClient that 
uses Hazelcast as the backing cache. This service relies on " +
+        "an abstracted repository manages the actual Hazelcast calls, provided 
by HazelcastConnectionService.")
+public class HazelcastMapCacheClient extends AbstractControllerService 
implements AtomicDistributedMapCacheClient<Long> {
+
+    public static final PropertyDescriptor HAZELCAST_CACHE_MANAGER = new 
PropertyDescriptor.Builder()
+            .name("hazelcast-cache-manager")
+            .displayName("Hazelcast Cache Manager")
+            .description("A Hazelcast Cache Manager which manages connections 
to Hazelcast and provides cache instances")
+            .identifiesControllerService(HazelcastCacheManager.class)
+            .required(true)
+            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+            .build();
+
+    public static final PropertyDescriptor HAZELCAST_CACHE_NAME = new 
PropertyDescriptor.Builder()
+            .name("hazelcast-cache-name")
+            .displayName("Hazelcast Cache Name")
+            .description("The name of a given repository. A Hazelcast cluster 
may handle multiple independent caches, each identified by a name." +

Review comment:
       "repository" is not a Hazelcast term. Why don't we use "cache" instead?

##########
File path: 
nifi-nar-bundles/nifi-hazelcast-bundle/nifi-hazelcast-services/src/main/java/org/apache/nifi/hazelcast/services/cacheclient/HazelcastMapCacheClient.java
##########
@@ -0,0 +1,254 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hazelcast.services.cacheclient;
+
+import org.apache.nifi.annotation.documentation.CapabilityDescription;
+import org.apache.nifi.annotation.documentation.Tags;
+import org.apache.nifi.annotation.lifecycle.OnDisabled;
+import org.apache.nifi.annotation.lifecycle.OnEnabled;
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.controller.AbstractControllerService;
+import org.apache.nifi.controller.ConfigurationContext;
+import org.apache.nifi.distributed.cache.client.AtomicCacheEntry;
+import 
org.apache.nifi.distributed.cache.client.AtomicDistributedMapCacheClient;
+import org.apache.nifi.distributed.cache.client.Deserializer;
+import org.apache.nifi.distributed.cache.client.Serializer;
+import org.apache.nifi.expression.ExpressionLanguageScope;
+import org.apache.nifi.hazelcast.services.cache.HazelcastCache;
+import org.apache.nifi.hazelcast.services.cachemanager.HazelcastCacheManager;
+import org.apache.nifi.hazelcast.services.util.LongUtil;
+import org.apache.nifi.processor.util.StandardValidators;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+import java.util.regex.Pattern;
+
+/**
+ * An implementation of DistributedMapCacheClient that uses Hazelcast as the 
backing cache.
+ *
+ * Note: By design, the client should not directly depend on Hazelcast 
specific classes to allow easy version and implementation changes.
+ */
+@Tags({ "hazelcast", "cache", "map"})
+@CapabilityDescription("An implementation of DistributedMapCacheClient that 
uses Hazelcast as the backing cache. This service relies on " +
+        "an abstracted repository manages the actual Hazelcast calls, provided 
by HazelcastConnectionService.")
+public class HazelcastMapCacheClient extends AbstractControllerService 
implements AtomicDistributedMapCacheClient<Long> {
+
+    public static final PropertyDescriptor HAZELCAST_CACHE_MANAGER = new 
PropertyDescriptor.Builder()
+            .name("hazelcast-cache-manager")
+            .displayName("Hazelcast Cache Manager")
+            .description("A Hazelcast Cache Manager which manages connections 
to Hazelcast and provides cache instances")
+            .identifiesControllerService(HazelcastCacheManager.class)
+            .required(true)
+            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+            .build();
+
+    public static final PropertyDescriptor HAZELCAST_CACHE_NAME = new 
PropertyDescriptor.Builder()
+            .name("hazelcast-cache-name")
+            .displayName("Hazelcast Cache Name")
+            .description("The name of a given repository. A Hazelcast cluster 
may handle multiple independent caches, each identified by a name." +
+                    "Clients using caches with the same name are working on 
the same repository.")

Review comment:
       Minor typo: no space between the sentences.

##########
File path: 
nifi-nar-bundles/nifi-hazelcast-bundle/nifi-hazelcast-services/src/main/java/org/apache/nifi/hazelcast/services/cache/IMapBasedHazelcastCache.java
##########
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hazelcast.services.cache;
+
+import com.hazelcast.map.IMap;
+import com.hazelcast.map.ReachedMaxSizeException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+
+/**
+ * Implementation of {@link HazelcastCache} backed by Hazelcast's IMap data 
structure. It's purpose is to wrap Hazelcast implementation specific details in 
order to
+ * make it possible to easily change version or data structure.
+ */
+public class IMapBasedHazelcastCache implements HazelcastCache {
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(IMapBasedHazelcastCache.class);
+
+    private final String name;
+    private final long ttlInMillis;
+    private final IMap<String, byte[]> repository;
+
+    /**
+     * @param name Name of the cache stored for identification.

Review comment:
       Why is the `name` passed in as a separate parameter?
   It could be retrieved from IMap. In this case the "It should be the IMap 
with the same identifier as cache name." consistency constraint would not be 
needed.

##########
File path: 
nifi-nar-bundles/nifi-hazelcast-bundle/nifi-hazelcast-services/src/main/resources/docs/org.apache.nifi.hazelcast.services.cachemanager.EmbeddedHazelcastCacheManager/additionalDetails.html
##########
@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+<html lang="en">
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+      http://www.apache.org/licenses/LICENSE-2.0
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<head>
+    <meta charset="utf-8" />
+    <title>EmbeddedHazelcastCacheManager</title>
+    <link rel="stylesheet" href="/nifi-docs/css/component-usage.css" 
type="text/css" />
+</head>
+
+<>
+<h2>EmbeddedHazelcastCacheManager</h2>
+
+<p>
+    This service starts and manages an embedded Hazelcast instance. The cache 
manager has direct accesses to the
+    instance - and the data stored in it. However, the instance sill opens a 
port for potential clients to join and
+    this cannot be prevented. Note that this might leave the instance open for 
rogue clients to join.
+</p>
+
+<p>
+    It is possible to have multiple independent Hazelcast instances on the 
same host (whether via EmbeddedHazelcastCacheManager
+    or externally) without any interference by setting the properties 
accordingly. If there are no other instances, the port number
+    and cluster name are not necessary to be set. (Default values will be used 
instead.)
+</p>
+
+<p>
+    The service supports multiple ways to set up a Hazelcast cluster. This is 
controlled by the property, named "Hazelcast High
+    Availability Mode". The following values might be used:

Review comment:
       I see it is a bigger refactor but I would consider to rename it to 
"Hazelcast Clustering Mode" with values "None", "All nodes", and "Explicit 
nodes".
   
   I have 2 problems with the current name / values:
   - "None" means not only non-HA but separate local caches, so it has a 
different semantics which is not related to HA/non-HA
   - both "Cluster" and "Explicit" are clustered, it is not really 
straightforward that "Cluster" means NiFi cluster here
   
   I would also suggest making "All nodes" (currently "Cluster") the default 
value.

##########
File path: 
nifi-nar-bundles/nifi-hazelcast-bundle/nifi-hazelcast-services/src/main/resources/docs/org.apache.nifi.hazelcast.services.cachemanager.EmbeddedHazelcastCacheManager/additionalDetails.html
##########
@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+<html lang="en">
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+      http://www.apache.org/licenses/LICENSE-2.0
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<head>
+    <meta charset="utf-8" />
+    <title>EmbeddedHazelcastCacheManager</title>
+    <link rel="stylesheet" href="/nifi-docs/css/component-usage.css" 
type="text/css" />
+</head>
+
+<>
+<h2>EmbeddedHazelcastCacheManager</h2>
+
+<p>
+    This service starts and manages an embedded Hazelcast instance. The cache 
manager has direct accesses to the
+    instance - and the data stored in it. However, the instance sill opens a 
port for potential clients to join and
+    this cannot be prevented. Note that this might leave the instance open for 
rogue clients to join.
+</p>
+
+<p>
+    It is possible to have multiple independent Hazelcast instances on the 
same host (whether via EmbeddedHazelcastCacheManager
+    or externally) without any interference by setting the properties 
accordingly. If there are no other instances, the port number
+    and cluster name are not necessary to be set. (Default values will be used 
instead.)

Review comment:
       I would rather say:
   "If there are no other instances, the default cluster name and port number 
can simply be used."

##########
File path: 
nifi-nar-bundles/nifi-hazelcast-bundle/nifi-hazelcast-services/src/main/java/org/apache/nifi/hazelcast/services/cachemanager/StandaloneHazelcastCacheManager.java
##########
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hazelcast.services.cachemanager;
+
+import com.hazelcast.core.HazelcastInstance;
+import org.apache.nifi.annotation.documentation.CapabilityDescription;
+import org.apache.nifi.annotation.documentation.Tags;
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.components.ValidationContext;
+import org.apache.nifi.components.ValidationResult;
+import org.apache.nifi.controller.ConfigurationContext;
+import org.apache.nifi.expression.ExpressionLanguageScope;
+import org.apache.nifi.processor.util.StandardValidators;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+@Tags({"hazelcast", "cache"})
+@CapabilityDescription("A service that provides cache instances backed by 
Hazelcast running outside of NiFi.")
+public class StandaloneHazelcastCacheManager extends 
IMapBasedHazelcastCacheManager {

Review comment:
       I would consider to rename it to `ExternalHazelcastCacheManager` or 
similar.
   "Stanadalone" is often used in the meaning of "non-clustered" which is a bit 
misleading here because the CS will typically connect to clusters.
   Embedded vs. External sounds to me more natural than Embedded vs. Standalone.

##########
File path: 
nifi-nar-bundles/nifi-hazelcast-bundle/nifi-hazelcast-services/src/main/java/org/apache/nifi/hazelcast/services/cachemanager/StandaloneHazelcastCacheManager.java
##########
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hazelcast.services.cachemanager;
+
+import com.hazelcast.core.HazelcastInstance;
+import org.apache.nifi.annotation.documentation.CapabilityDescription;
+import org.apache.nifi.annotation.documentation.Tags;
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.components.ValidationContext;
+import org.apache.nifi.components.ValidationResult;
+import org.apache.nifi.controller.ConfigurationContext;
+import org.apache.nifi.expression.ExpressionLanguageScope;
+import org.apache.nifi.processor.util.StandardValidators;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+@Tags({"hazelcast", "cache"})
+@CapabilityDescription("A service that provides cache instances backed by 
Hazelcast running outside of NiFi.")
+public class StandaloneHazelcastCacheManager extends 
IMapBasedHazelcastCacheManager {
+
+    public static final PropertyDescriptor HAZELCAST_SERVER_ADDRESS = new 
PropertyDescriptor.Builder()
+            .name("hazelcast-server-address")
+            .displayName("Hazelcast Server Address")
+            .description("Addresses of one or more the Hazelcast instances, 
using {host:port} format, separated by " + ADDRESS_SEPARATOR + ".")

Review comment:
       `...separated by comma.` would be more readable than `...separated by ,.`

##########
File path: 
nifi-nar-bundles/nifi-hazelcast-bundle/nifi-hazelcast-services/src/main/java/org/apache/nifi/hazelcast/services/cacheclient/HazelcastMapCacheClient.java
##########
@@ -0,0 +1,254 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hazelcast.services.cacheclient;
+
+import org.apache.nifi.annotation.documentation.CapabilityDescription;
+import org.apache.nifi.annotation.documentation.Tags;
+import org.apache.nifi.annotation.lifecycle.OnDisabled;
+import org.apache.nifi.annotation.lifecycle.OnEnabled;
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.controller.AbstractControllerService;
+import org.apache.nifi.controller.ConfigurationContext;
+import org.apache.nifi.distributed.cache.client.AtomicCacheEntry;
+import 
org.apache.nifi.distributed.cache.client.AtomicDistributedMapCacheClient;
+import org.apache.nifi.distributed.cache.client.Deserializer;
+import org.apache.nifi.distributed.cache.client.Serializer;
+import org.apache.nifi.expression.ExpressionLanguageScope;
+import org.apache.nifi.hazelcast.services.cache.HazelcastCache;
+import org.apache.nifi.hazelcast.services.cachemanager.HazelcastCacheManager;
+import org.apache.nifi.hazelcast.services.util.LongUtil;
+import org.apache.nifi.processor.util.StandardValidators;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+import java.util.regex.Pattern;
+
+/**
+ * An implementation of DistributedMapCacheClient that uses Hazelcast as the 
backing cache.
+ *
+ * Note: By design, the client should not directly depend on Hazelcast 
specific classes to allow easy version and implementation changes.
+ */
+@Tags({ "hazelcast", "cache", "map"})
+@CapabilityDescription("An implementation of DistributedMapCacheClient that 
uses Hazelcast as the backing cache. This service relies on " +
+        "an abstracted repository manages the actual Hazelcast calls, provided 
by HazelcastConnectionService.")
+public class HazelcastMapCacheClient extends AbstractControllerService 
implements AtomicDistributedMapCacheClient<Long> {
+
+    public static final PropertyDescriptor HAZELCAST_CACHE_MANAGER = new 
PropertyDescriptor.Builder()
+            .name("hazelcast-cache-manager")
+            .displayName("Hazelcast Cache Manager")
+            .description("A Hazelcast Cache Manager which manages connections 
to Hazelcast and provides cache instances")

Review comment:
       Minor typo: missing period at the end of the sentence.

##########
File path: 
nifi-nar-bundles/nifi-hazelcast-bundle/nifi-hazelcast-services/src/main/resources/docs/org.apache.nifi.hazelcast.services.cachemanager.EmbeddedHazelcastCacheManager/additionalDetails.html
##########
@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+<html lang="en">
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+      http://www.apache.org/licenses/LICENSE-2.0
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<head>
+    <meta charset="utf-8" />
+    <title>EmbeddedHazelcastCacheManager</title>
+    <link rel="stylesheet" href="/nifi-docs/css/component-usage.css" 
type="text/css" />
+</head>
+
+<>
+<h2>EmbeddedHazelcastCacheManager</h2>
+
+<p>
+    This service starts and manages an embedded Hazelcast instance. The cache 
manager has direct accesses to the
+    instance - and the data stored in it. However, the instance sill opens a 
port for potential clients to join and
+    this cannot be prevented. Note that this might leave the instance open for 
rogue clients to join.
+</p>
+
+<p>
+    It is possible to have multiple independent Hazelcast instances on the 
same host (whether via EmbeddedHazelcastCacheManager
+    or externally) without any interference by setting the properties 
accordingly. If there are no other instances, the port number
+    and cluster name are not necessary to be set. (Default values will be used 
instead.)
+</p>
+
+<p>
+    The service supports multiple ways to set up a Hazelcast cluster. This is 
controlled by the property, named "Hazelcast High
+    Availability Mode". The following values might be used:
+</p>
+
+<h3>None</h3>
+
+<p>
+    This is the default value. Used when sharing data between nodes is not 
required. With this value, every NiFi node
+    in the cluster (if it is clustered) connects to its local Hazelcast server 
only. The Hazelcast servers do not form a cluster.
+</p>
+
+<h3>Cluster</h3>
+
+<p>
+    Can be used only in clustered node. Using this mode will result a single 
Hazelcast cluster consisting of the embedded instances
+    of all the NiFi nodes. This mode requires all Hazelcast servers listening 
on the same port. Having different port numbers
+    (based on expression for example) would prevent the cluster from forming.
+</p>
+
+<p>
+    The controller service automatically gathers the host list from the NiFi 
cluster itself when it is enabled. It is
+    not required for all the nodes to have been successfully joined at this 
point, but the join must have been initiated. When
+    the controller service is enabled at the start of the NiFi instance, the 
enabling of the service will be prevented until the
+    node is considered clustered.
+</p>
+
+<p>
+    Hazelcast can accept nodes that join at a later time. As the new node has 
a comprehensive list of the expected instances - including the
+    already existing ones and itself - Hazelcast will be able to reach the 
expected state. Beware: this may take significant time.
+    <i>Note: as this is provided by Hazelcast, it is not guaranteed that later 
releases will have the exact same behaviour!</i>

Review comment:
       In my opinion it is the NiFi contributors' responsibility to provide 
backward compatible solutions when they decide to upgrade (or not to upgrade) 
Hazelcast. So it is not really something the end user should be warned now.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to