summaryrefslogtreecommitdiff
path: root/eaaf_core_utils/src
diff options
context:
space:
mode:
Diffstat (limited to 'eaaf_core_utils/src')
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/support/SecureRandomHolder.java92
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/logging/SimpleStatusMessager.java62
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/ArrayUtils.java62
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DataURLBuilder.java113
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DataUrlBuilder.java91
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/FileUtils.java257
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HTTPUtils.java178
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HttpClientFactory.java711
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HttpUtils.java119
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/IHttpClientFactory.java29
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyStoreUtils.java248
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyValueUtils.java697
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/NodeIteratorAdapter.java88
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/NodeListAdapter.java64
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/Random.java290
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SecurePendingRequestIdGenerationStrategy.java390
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/ServletUtils.java64
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SimplePendingRequestIdGenerationStrategy.java58
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/StreamUtils.java177
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/TransactionIDUtils.java101
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/TransactionIdUtils.java94
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/X509Utils.java87
-rw-r--r--eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/impl/logging/JUnitTestStatusMessenger.java97
-rw-r--r--eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/impl/utils/test/KeyValueUtilsTest.java446
24 files changed, 2511 insertions, 2104 deletions
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/support/SecureRandomHolder.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/support/SecureRandomHolder.java
index a297367f..8584d63f 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/support/SecureRandomHolder.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/support/SecureRandomHolder.java
@@ -1,61 +1,57 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.core.impl.idp.process.support;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
/**
- * Holder for a secure random instance following the initialization on demand holder design pattern. The secure random
- * instance is a singleton that is initialized on first usage.
- *
+ * Holder for a secure random instance following the initialization on demand holder design pattern.
+ * The secure random instance is a singleton that is initialized on first usage.
+ *
* @author tknall
- *
+ *
*/
public class SecureRandomHolder {
- private SecureRandomHolder() {
- }
-
- private static final SecureRandom SRND_INSTANCE;
- static {
- try {
- SRND_INSTANCE = SecureRandom.getInstance("SHA1PRNG");
- } catch (NoSuchAlgorithmException e) {
- throw new RuntimeException("Unable to instantiate SHA1PRNG.", e);
- }
- }
-
- /**
- * Returns a secure random generator instance.
- * @return The secure random instance.
- */
- public static SecureRandom getInstance() {
- return SecureRandomHolder.SRND_INSTANCE;
- }
-
-} \ No newline at end of file
+ private SecureRandomHolder() {
+
+ }
+
+ private static final SecureRandom SRND_INSTANCE;
+
+ static {
+ try {
+ SRND_INSTANCE = SecureRandom.getInstance("SHA1PRNG");
+ } catch (final NoSuchAlgorithmException e) {
+ throw new RuntimeException("Unable to instantiate SHA1PRNG.", e);
+ }
+ }
+
+ /**
+ * Returns a secure random generator instance.
+ *
+ * @return The secure random instance.
+ */
+ public static SecureRandom getInstance() {
+ return SecureRandomHolder.SRND_INSTANCE;
+ }
+
+}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/logging/SimpleStatusMessager.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/logging/SimpleStatusMessager.java
index d36c79b9..5715a7b6 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/logging/SimpleStatusMessager.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/logging/SimpleStatusMessager.java
@@ -1,44 +1,44 @@
package at.gv.egiz.eaaf.core.impl.logging;
import java.text.MessageFormat;
-
import at.gv.egiz.eaaf.core.api.IStatusMessenger;
/**
- * Simple {@link IStatusMessenger} implementation that formats messages by using {@link MessageFormat}
- *
+ * Simple {@link IStatusMessenger} implementation that formats messages by using.
+ * {@link MessageFormat}
+ *
* @author tlenz
*
*/
public class SimpleStatusMessager implements IStatusMessenger {
- private static final String NOTSUPPORTED = "Error response-codes not supported";
- private static final String NULLMESSAGE = "No error-message provided";
-
- @Override
- public String getMessage(String messageId, Object[] parameters) {
- return getMessageWithoutDefault(messageId, parameters);
-
- }
-
- @Override
- public String getMessageWithoutDefault(String messageId, Object[] parameters) {
- if (messageId != null) {
- return MessageFormat.format(messageId, parameters);
-
- }
-
- return NULLMESSAGE;
- }
-
- @Override
- public String getResponseErrorCode(Throwable throwable) {
- return NOTSUPPORTED;
- }
-
- @Override
- public String mapInternalErrorToExternalError(String intErrorCode) {
- return NOTSUPPORTED;
- }
+ private static final String NOTSUPPORTED = "Error response-codes not supported";
+ private static final String NULLMESSAGE = "No error-message provided";
+
+ @Override
+ public String getMessage(final String messageId, final Object[] parameters) {
+ return getMessageWithoutDefault(messageId, parameters);
+
+ }
+
+ @Override
+ public String getMessageWithoutDefault(final String messageId, final Object[] parameters) {
+ if (messageId != null) {
+ return MessageFormat.format(messageId, parameters);
+
+ }
+
+ return NULLMESSAGE;
+ }
+
+ @Override
+ public String getResponseErrorCode(final Throwable throwable) {
+ return NOTSUPPORTED;
+ }
+
+ @Override
+ public String mapInternalErrorToExternalError(final String intErrorCode) {
+ return NOTSUPPORTED;
+ }
}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/ArrayUtils.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/ArrayUtils.java
index 8585bc05..1da82f43 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/ArrayUtils.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/ArrayUtils.java
@@ -1,44 +1,42 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
package at.gv.egiz.eaaf.core.impl.utils;
import java.util.List;
public class ArrayUtils {
- /**
- * Check if a String 's' is part of a List 'l' in qualsIgnoreCase mode
- *
- * @param s Search String
- * @param l List of String elements
- * @return true if 's' is in 'l', otherwise false
- */
- public static boolean containsCaseInsensitive(String s, List<String> l){
- if (l == null || s == null)
- return false;
-
- return l.stream().anyMatch(x -> x.equalsIgnoreCase(s));
-
+ /**
+ * Check if a String 's' is part of a List 'l' in qualsIgnoreCase mode.
+ *
+ * @param s Search String
+ * @param l List of String elements
+ * @return true if 's' is in 'l', otherwise false
+ */
+ public static boolean containsCaseInsensitive(final String s, final List<String> l) {
+ if (l == null || s == null) {
+ return false;
}
+ return l.stream().anyMatch(x -> x.equalsIgnoreCase(s));
+
+ }
+
}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DataURLBuilder.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DataURLBuilder.java
deleted file mode 100644
index a81fafbc..00000000
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DataURLBuilder.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*******************************************************************************
- * Copyright 2014 Federal Chancellery Austria
- * MOA-ID has been developed in a cooperation between BRZ, the Federal
- * Chancellery Austria - ICT staff unit, and Graz University of Technology.
- *
- * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- * http://www.osor.eu/eupl/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- ******************************************************************************/
-/*
- * Copyright 2003 Federal Chancellery Austria
- * MOA-ID has been developed in a cooperation between BRZ, the Federal
- * Chancellery Austria - ICT staff unit, and Graz University of Technology.
- *
- * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- * http://www.osor.eu/eupl/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- */
-
-
-package at.gv.egiz.eaaf.core.impl.utils;
-
-import org.apache.commons.lang3.StringUtils;
-
-import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
-
-/**
- * Builds a DataURL parameter meant for the security layer implementation
- * to respond to.
- *
- * @author Paul Ivancsics
- * @version $Id$
- */
-public class DataURLBuilder {
-
- /**
- * Constructor for DataURLBuilder.
- */
- public DataURLBuilder() {
- super();
- }
-
- /**
- * Constructs a data URL for <code>VerifyIdentityLink</code> or <code>VerifyAuthenticationBlock</code>,
- * including the <code>MOASessionID</code> as a parameter.
- *
- * @param authBaseURL base URL (context path) of the MOA ID Authentication component,
- * including a trailing <code>'/'</code>
- * @param authServletName request part of the data URL
- * @param pendingReqId sessionID to be included in the dataURL
- * @return String
- */
- public String buildDataURL(String authBaseURL, String authServletName, String pendingReqId) {
- String dataURL;
- if (!authBaseURL.endsWith("/"))
- authBaseURL += "/";
-
- if (authServletName.startsWith("/"))
- authServletName = authServletName.substring(1);
-
- dataURL = authBaseURL + authServletName;
-
- if (StringUtils.isNotEmpty(pendingReqId))
- dataURL = addParameter(dataURL, EAAFConstants.PARAM_HTTP_TARGET_PENDINGREQUESTID, pendingReqId);
-
- return dataURL;
- }
-
- /**
- * Method addParameter.
- * @param urlString represents the url
- * @param paramname is the parameter to be added
- * @param value is the value of that parameter
- * @return String
- */
- private String addParameter(String urlString, String paramname, String value) {
- String url = urlString;
- if (paramname != null) {
- if (url.indexOf("?") < 0)
- url += "?";
- else
- url += "&";
- url += paramname + "=" + value;
- }
- return url;
- }
-}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DataUrlBuilder.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DataUrlBuilder.java
new file mode 100644
index 00000000..a72e07dd
--- /dev/null
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DataUrlBuilder.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria MOA-ID has been developed in a cooperation between
+ * BRZ, the Federal Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at: http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+package at.gv.egiz.eaaf.core.impl.utils;
+
+import org.apache.commons.lang3.StringUtils;
+
+import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
+
+/**
+ * Builds a DataURL parameter meant for the security layer implementation to respond to.
+ *
+ * @author Paul Ivancsics
+ * @version $Id$
+ */
+public class DataUrlBuilder {
+
+ /**
+ * Constructor for DataURLBuilder.
+ */
+ public DataUrlBuilder() {
+ super();
+ }
+
+ /**
+ * Constructs a data URL for <code>VerifyIdentityLink</code> or
+ * <code>VerifyAuthenticationBlock</code>, including the <code>MOASessionID</code> as a parameter.
+ *
+ * @param authBaseUrl base URL (context path) of the MOA ID Authentication component, including a
+ * trailing <code>'/'</code>
+ * @param authServletName request part of the data URL
+ * @param pendingReqId sessionID to be included in the dataURL
+ * @return String
+ */
+ public String buildDataUrl(String authBaseUrl, String authServletName,
+ final String pendingReqId) {
+ String dataUrl;
+ if (!authBaseUrl.endsWith("/")) {
+ authBaseUrl += "/";
+ }
+
+ if (authServletName.startsWith("/")) {
+ authServletName = authServletName.substring(1);
+ }
+
+ dataUrl = authBaseUrl + authServletName;
+
+ if (StringUtils.isNotEmpty(pendingReqId)) {
+ dataUrl =
+ addParameter(dataUrl, EAAFConstants.PARAM_HTTP_TARGET_PENDINGREQUESTID, pendingReqId);
+ }
+
+ return dataUrl;
+ }
+
+ /**
+ * Method addParameter.
+ *
+ * @param urlString represents the url
+ * @param paramname is the parameter to be added
+ * @param value is the value of that parameter
+ * @return String
+ */
+ private String addParameter(final String urlString, final String paramname, final String value) {
+ String url = urlString;
+ if (paramname != null) {
+ if (url.indexOf("?") < 0) {
+ url += "?";
+ } else {
+ url += "&";
+ }
+ url += paramname + "=" + value;
+ }
+ return url;
+ }
+}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/FileUtils.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/FileUtils.java
index 6ac51ac4..943d3dad 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/FileUtils.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/FileUtils.java
@@ -1,29 +1,22 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
package at.gv.egiz.eaaf.core.impl.utils;
@@ -38,22 +31,22 @@ import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
-
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FileUtils {
- private static final Logger log = LoggerFactory.getLogger(FileUtils.class);
-
-
+ private static final Logger log = LoggerFactory.getLogger(FileUtils.class);
+
+
/**
* Reads a file, given by URL, into a byte array.
+ *
* @param urlString file URL
* @return file content
* @throws IOException on any exception thrown
*/
- public static byte[] readURL(String urlString) throws IOException {
+ public static byte[] readUrl(final String urlString) throws IOException {
final URL url = new URL(urlString);
final InputStream in = new BufferedInputStream(url.openStream());
final byte[] content = StreamUtils.readStream(in);
@@ -63,114 +56,142 @@ public class FileUtils {
/**
* Reads a file from a resource.
+ *
* @param name resource name
* @return file content as a byte array
* @throws IOException on any exception thrown
*/
- public static byte[] readResource(String name) throws IOException {
+ public static byte[] readResource(final String name) throws IOException {
final ClassLoader cl = FileUtils.class.getClassLoader();
final BufferedInputStream in = new BufferedInputStream(cl.getResourceAsStream(name));
final byte[] content = StreamUtils.readStream(in);
in.close();
return content;
}
+
/**
* Reads a file from a resource.
+ *
* @param name filename
* @param encoding character encoding
* @return file content
* @throws IOException on any exception thrown
*/
- public static String readResource(String name, String encoding) throws IOException {
+ public static String readResource(final String name, final String encoding) throws IOException {
final byte[] content = readResource(name);
return new String(content, encoding);
}
-
-
- /**
- * Returns the absolute URL of a given url which is relative to the parameter root
- * @param url
- * @param root
- * @return String
- * @throws MalformedURLException
- */
- public static String makeAbsoluteURL(String url, URI root) throws MalformedURLException {
- if (root != null)
- return makeAbsoluteURL(url, root.toURL().toString());
- else
- return makeAbsoluteURL(url, StringUtils.EMPTY);
-
- }
-
- /**
- * Returns the absolute URL of a given url which is relative to the parameter root
- * @param url
- * @param root
- * @return String
- */
- public static String makeAbsoluteURL(String url, String root) {
- //if url is relative to rootConfigFileDirName make it absolute
-
- log.trace("Making AbsoluteURL URL: " + url + " Root-Path: " + root);
-
- if (StringUtils.isEmpty(root))
- root = null;
-
- File keyFile;
- String newURL = url;
-
- if(null == url) return null;
-
- if (url.startsWith("http:") || url.startsWith("https:") || url.startsWith("file:")
- || url.startsWith("ftp:") || url.startsWith("classpath:")) {
- return url;
-
- } else {
- // check if absolute - if not make it absolute
- keyFile = new File(url);
- if (!keyFile.isAbsolute()) {
- keyFile = new File(root, url);
-
- if (keyFile.toString().startsWith("file:"))
- newURL = keyFile.toString();
-
- else
- newURL = keyFile.toURI().toString();
-
- }
- return newURL;
- }
- }
-
-
- private static void copy( InputStream fis, OutputStream fos )
- {
- try
- {
- final byte[] buffer = new byte[ 0xFFFF ];
- for ( int len; (len = fis.read(buffer)) != -1; )
- fos.write( buffer, 0, len );
- }
- catch( final IOException e ) {
- System.err.println( e );
- }
- finally {
- if ( fis != null )
- try { fis.close(); } catch ( final IOException e ) { e.printStackTrace(); }
- if ( fos != null )
- try { fos.close(); } catch ( final IOException e ) { e.printStackTrace(); }
- }
- }
-
- public static void copyFile(File src, File dest)
- {
- try
- {
- copy( new FileInputStream( src ), new FileOutputStream( dest ) );
- }
- catch( final IOException e ) {
- e.printStackTrace();
- }
- }
-
+
+
+ /**
+ * Returns the absolute URL of a given url which is relative to the parameter root.
+ *
+ * @param url Filepath
+ * @param root configuration root context
+ * @return absolut filepath
+ * @throws MalformedURLException In case of a filepath error
+ */
+ public static String makeAbsoluteUrl(final String url, final URI root)
+ throws MalformedURLException {
+ if (root != null) {
+ return makeAbsoluteUrl(url, root.toURL().toString());
+ } else {
+ return makeAbsoluteUrl(url, StringUtils.EMPTY);
+ }
+
+ }
+
+ /**
+ * Returns the absolute URL of a given url which is relative to the parameter root.
+ *
+ * @param url Filepath
+ * @param root configuration root context
+ * @return absolut filepath
+ */
+ public static String makeAbsoluteUrl(final String url, String root) {
+ // if url is relative to rootConfigFileDirName make it absolute
+
+ log.trace("Making AbsoluteURL URL: " + url + " Root-Path: " + root);
+
+ if (StringUtils.isEmpty(root)) {
+ root = null;
+ }
+
+ File keyFile;
+ String newUrl = url;
+
+ if (null == url) {
+ return null;
+ }
+
+ if (url.startsWith("http:") || url.startsWith("https:") || url.startsWith("file:")
+ || url.startsWith("ftp:") || url.startsWith("classpath:")) {
+ return url;
+
+ } else {
+ // check if absolute - if not make it absolute
+ keyFile = new File(url);
+ if (!keyFile.isAbsolute()) {
+ keyFile = new File(root, url);
+
+ if (keyFile.toString().startsWith("file:")) {
+ newUrl = keyFile.toString();
+ } else {
+ newUrl = keyFile.toURI().toString();
+ }
+
+ }
+ return newUrl;
+ }
+ }
+
+
+ private static void copy(final InputStream fis, final OutputStream fos) {
+ try {
+ final byte[] buffer = new byte[0xFFFF];
+ for (int len; (len = fis.read(buffer)) != -1;) {
+ fos.write(buffer, 0, len);
+ }
+ } catch (final IOException e) {
+ System.err.println(e);
+
+ }
+ }
+
+ /**
+ * Copy file from source to destination.
+ *
+ * @param src File source
+ * @param dest file destination
+ */
+ public static void copyFile(final File src, final File dest) {
+ InputStream fis = null;
+ OutputStream fos = null;
+
+ try {
+ fis = new FileInputStream(src);
+ fos = new FileOutputStream(src);
+ copy(fis, fos);
+
+ } catch (final IOException e) {
+ e.printStackTrace();
+
+ } finally {
+ if (fis != null) {
+ try {
+ fis.close();
+ } catch (final IOException e) {
+ e.printStackTrace();
+ }
+ }
+ if (fos != null) {
+ try {
+ fos.close();
+ } catch (final IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HTTPUtils.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HTTPUtils.java
deleted file mode 100644
index cf1abaa7..00000000
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HTTPUtils.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*******************************************************************************
- * Copyright 2014 Federal Chancellery Austria
- * MOA-ID has been developed in a cooperation between BRZ, the Federal
- * Chancellery Austria - ICT staff unit, and Graz University of Technology.
- *
- * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- * http://www.osor.eu/eupl/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- ******************************************************************************/
-/*
- * Copyright 2003 Federal Chancellery Austria
- * MOA-ID has been developed in a cooperation between BRZ, the Federal
- * Chancellery Austria - ICT staff unit, and Graz University of Technology.
- *
- * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- * http://www.osor.eu/eupl/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- */
-
-
-package at.gv.egiz.eaaf.core.impl.utils;
-
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.commons.lang3.StringUtils;
-
-
-/**
- *
- * @author Rudolf Schamberger
- *
- */
-public class HTTPUtils {
-
-// /**
-// * Utility used to obtainin correct encoded HTTP content.
-// * Reads a given Content adressed by HTTP-URL into String.
-// * Content encoding is considered by using the Content-Type HTTP header charset value.
-// * @param URL HTTP URL to read from.
-// * @return String representation of content
-// * @throws IOException on data-reading problems
-// */
-// public static String readHttpURL(String URL)
-// throws IOException {
-//
-// URL url = new URL(URL);
-// HttpURLConnection conn = (HttpURLConnection)url.openConnection();
-// conn.setRequestMethod("GET");
-// String contentType = conn.getContentType();
-// RE regExp = null;
-// try {
-// regExp = new RE("(;.*charset=)(\"*)(.*[^\"])");
-// } catch (RESyntaxException e) {
-// //RESyntaxException is not possible = expr. is costant
-// }
-// boolean charsetSupplied = regExp.match(contentType);
-// String encoding = "ISO-8859-1"; //default HTTP encoding
-// if (charsetSupplied) {
-// encoding = regExp.getParen(3);
-// }
-// InputStream instream = new BufferedInputStream(conn.getInputStream());
-// InputStreamReader isr = new InputStreamReader(instream, encoding);
-// Reader in = new BufferedReader(isr);
-// int ch;
-// StringBuffer buffer = new StringBuffer();
-// while ((ch = in.read()) > -1) {
-// buffer.append((char)ch);
-// }
-// in.close();
-// conn.disconnect();
-// return buffer.toString();
-// }
-
- /**
- * Helper method to retrieve server URL including context path
- * @param request HttpServletRequest
- * @return Server URL including context path (e.g. http://localhost:8443/moa-id-auth
- */
- public static String getBaseURL(HttpServletRequest request) {
- StringBuffer buffer = new StringBuffer(getServerURL(request));
-
- // add context path if available
- String contextPath = request.getContextPath();
- if (!StringUtils.isEmpty(contextPath)) {
- buffer.append(contextPath);
- }
-
- return buffer.toString();
- }
-
- /**
- * Helper method to retrieve server URL
- * @param request HttpServletRequest
- * @return Server URL (e.g. http://localhost:8443)
- */
- public static String getServerURL(HttpServletRequest request) {
- StringBuffer buffer = new StringBuffer();
-
- // get protocol
- String protocol = request.getScheme();
- buffer.append(protocol).append("://");
-
- // server name
- buffer.append(request.getServerName());
-
- // add port if necessary
- int port = request.getServerPort();
- if ((protocol.equals("http") && port != 80) || (protocol.equals("https") && port != 443)) {
- buffer.append(':');
- buffer.append(port);
- }
-
- return buffer.toString();
- }
-
- /**
- * Extract the IDP PublicURLPrefix from authrequest
- *
- * @param req HttpServletRequest
- * @return PublicURLPrefix <String> which ends always without /
- */
- public static String extractAuthURLFromRequest(HttpServletRequest req) {
- String authURL = req.getScheme() + "://" + req.getServerName();
- if ((req.getScheme().equalsIgnoreCase("https") && req.getServerPort()!=443) || (req.getScheme().equalsIgnoreCase("http") && req.getServerPort()!=80)) {
- authURL = authURL.concat(":" + req.getServerPort());
- }
- authURL = authURL.concat(req.getContextPath());
- return authURL;
-
- }
-
- /**
- * Extract the IDP requested URL from authrequest
- *
- * @param req HttpServletRequest
- * @return RequestURL <String> which ends always without /
- */
- public static String extractAuthServletPathFromRequest(HttpServletRequest req) {
- return extractAuthURLFromRequest(req).concat(req.getServletPath());
-
- }
-
- public static String addURLParameter(String url, String paramname,
- String paramvalue) {
- String param = paramname + "=" + paramvalue;
- if (url.indexOf("?") < 0)
- return url + "?" + param;
- else
- return url + "&" + param;
- }
-
-}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HttpClientFactory.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HttpClientFactory.java
index a8cfa7c1..4e8be52e 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HttpClientFactory.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HttpClientFactory.java
@@ -8,11 +8,11 @@ import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
-
import javax.annotation.PostConstruct;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
-
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
@@ -44,339 +44,378 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
-import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
-import at.gv.egiz.eaaf.core.exceptions.EAAFConfigurationException;
-
public class HttpClientFactory implements IHttpClientFactory {
- private static final Logger log = LoggerFactory.getLogger(HttpClientFactory.class);
- @Autowired(required=true) private IConfiguration basicConfig;
- @Autowired(required=true) ResourceLoader resourceLoader;
-
- public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_USE = "client.http.connection.pool.use";
- public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXTOTAL = "client.http.connection.pool.maxtotal";
- public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXPERROUTE = "client.http.connection.pool.maxperroute";
- public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET = "client.http.connection.timeout.socket";
- public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION = "client.http.connection.timeout.connection";
- public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_REQUEST = "client.http.connection.timeout.request";
- public static final String PROP_CONFIG_CLIENT_HTTP_SSL_HOSTNAMEVERIFIER_TRUSTALL = "client.http.ssl.hostnameverifier.trustall";
-
- public static final String PROP_CONFIG_CLIENT_MODE = "client.authmode";
- public static final String PROP_CONFIG_CLIENT_AUTH_HTTP_USERNAME = "client.auth.http.username";
- public static final String PROP_CONFIG_CLIENT_AUTH_HTTP_PASSORD = "client.auth.http.password";
- public static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_PATH = "client.auth.ssl.keystore.path";
- public static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_PASSORD = "client.auth.ssl.keystore.password";
- public static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_TYPE = "client.auth.ssl.keystore.type";
- public static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEY_PASSWORD = "client.auth.ssl.key.password";
- public static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEY_ALIAS = "client.auth.ssl.key.alias";
-
- // default configuration values
- public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET = "15";
- public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION = "15";
- public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_REQUEST = "30";
- public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXTOTAL = "500";
- public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXPERROUTE = "100";
-
- public enum ClientAuthMode {
- NONE("none"),
- PASSWORD("password"),
- SSL("ssl");
-
- private final String mode;
-
- private ClientAuthMode(String mode) {
- this.mode = mode;
- }
-
- /**
- * Get the PVP mode
- *
- * @return
- */
- public String getMode() {
- return this.mode;
- }
-
- public static ClientAuthMode fromString(String s) {
- try {
- return ClientAuthMode.valueOf(s.toUpperCase());
-
- } catch (IllegalArgumentException|NullPointerException e) {
- return null;
- }
- }
-
- @Override
- public String toString() {
- return getMode();
-
- }
-
- };
-
- public enum KeyStoreType {
- PKCS12("pkcs12"),
- JKS("jks");
-
- private final String type;
-
- private KeyStoreType (String type) {
- this.type = type;
- }
-
- /**
- * Get the PVP mode
- *
- * @return
- */
- public String getType() {
- return this.type;
- }
-
- public static KeyStoreType fromString(String s) {
- try {
- return KeyStoreType.valueOf(s.toUpperCase());
-
- } catch (IllegalArgumentException|NullPointerException e) {
- return null;
- }
- }
-
- @Override
- public String toString() {
- return getType();
-
- }
-
- };
-
- private HttpClientBuilder httpClientBuilder = null;
-
- /* (non-Javadoc)
- * @see at.gv.egiz.eaaf.core.impl.utils.IHttpClientFactory#getHttpClient()
- */
- @Override
- public CloseableHttpClient getHttpClient() {
- return getHttpClient(true);
-
- }
-
- @Override
- public CloseableHttpClient getHttpClient(boolean followRedirects) {
- RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
- if (!followRedirects)
- redirectStrategy = new RedirectStrategy() {
-
- @Override
- public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context)
- throws ProtocolException {
- return false;
- }
-
- @Override
- public HttpUriRequest getRedirect(HttpRequest request, HttpResponse response, HttpContext context)
- throws ProtocolException {
- return null;
- }
- };
-
- return httpClientBuilder
- .setRedirectStrategy(redirectStrategy)
- .build();
-
- }
-
- @PostConstruct
- private void initalize() {
- //initialize http client
- log.trace("Initializing HTTP Client-builder ... ");
- httpClientBuilder = HttpClients.custom();
-
- //set default request configuration
- final RequestConfig requestConfig = RequestConfig.custom()
- .setConnectTimeout(Integer.valueOf(basicConfig.getBasicConfiguration(
- PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION,
- DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION)) * 1000)
- .setConnectionRequestTimeout(Integer.valueOf(basicConfig.getBasicConfiguration(
- PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_REQUEST,
- DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_REQUEST)) * 1000)
- .setSocketTimeout(Integer.valueOf(basicConfig.getBasicConfiguration(
- PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET,
- DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET)) * 1000)
- .build();
- httpClientBuilder.setDefaultRequestConfig(requestConfig);
-
- ClientAuthMode clientAuthMode = ClientAuthMode.fromString(
- basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_MODE, ClientAuthMode.NONE.getMode()));
- if (clientAuthMode == null) {
- log.warn("Can Not parse ClientAuthMode! Set mode to default value");
- clientAuthMode = ClientAuthMode.NONE;
-
- }
-
- //inject basic http authentication if required
- log.info("Client authentication-mode is set to: {}", clientAuthMode);
- injectBasicAuthenticationIfRequired(clientAuthMode);
-
- //inject authentication if required
- final LayeredConnectionSocketFactory sslConnectionFactory = getSSLContext(clientAuthMode);
-
- //set pool connection if required
- injectConnectionPoolIfRequired(sslConnectionFactory);
-
-
- }
-
- private void injectBasicAuthenticationIfRequired(ClientAuthMode clientAuthMode) {
- if (clientAuthMode.equals(ClientAuthMode.PASSWORD)) {
- final CredentialsProvider provider = new BasicCredentialsProvider();
-
- final String username = basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_HTTP_USERNAME);
- final String password = basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_HTTP_PASSORD);
-
- if (StringUtils.isEmpty(username)) {
- log.warn("Http basic authentication was activated but NOT username was set!");
-
- }
-
- log.trace("Injecting basic authentication with username: {} and password: {}", username, password);
- final UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(username, password);
- provider.setCredentials(AuthScope.ANY, credentials);
- httpClientBuilder.setDefaultCredentialsProvider(provider);
- log.info("Basic http authentication was injected with username: {}", username);
-
- } else {
- log.trace("Injection of Http Basic authentication was skipped");
-
- }
-
- }
-
- private SSLContext buildSSLContextWithSSLClientAuthentication() throws KeyManagementException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException, EAAFConfigurationException {
- log.trace("Injecting SSL client-authentication into http client ... ");
- final KeyStore keystore = getSSLAuthKeyStore();
- final String keyPasswordString = basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_SSL_KEY_PASSWORD);
- log.trace("Open SSL Client-Auth keystore with password: {}", keyPasswordString);
- final char[] keyPassword = (keyPasswordString == null) ? StringUtils.EMPTY.toCharArray() : keyPasswordString.toCharArray();
- return SSLContexts.custom().loadKeyMaterial(keystore, keyPassword).build();
-
- }
-
- private KeyStore getSSLAuthKeyStore() throws EAAFConfigurationException {
- final KeyStoreType keyStoreType = KeyStoreType.fromString(
- basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_TYPE, KeyStoreType.PKCS12.getType()));
- final String localKeyStorePath = basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_PATH, StringUtils.EMPTY);
- final String keyStorePassword = basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_PASSORD, StringUtils.EMPTY);
-
- try {
- log.debug("Open keyStore with type: {}", keyStoreType);
- KeyStore clientStore;
- if (keyStoreType.equals(KeyStoreType.PKCS12)) {
- clientStore = KeyStore.getInstance("pkcs12");
- } else {
- clientStore = KeyStore.getInstance("JKS");
- }
-
-
- log.debug("Read keyStore path: {} from configuration", localKeyStorePath);
- if (StringUtils.isNotEmpty(localKeyStorePath)) {
- final String absFilePath = FileUtils.makeAbsoluteURL(localKeyStorePath, basicConfig.getConfigurationRootDirectory());
- final Resource ressource = resourceLoader.getResource(absFilePath);
- final InputStream is = ressource.getInputStream();
- log.trace("Load keyStore: {} with password: {}", absFilePath, keyStorePassword);
- clientStore.load(is, keyStorePassword.toCharArray());
- is.close();
-
- return clientStore;
-
- } else {
- log.warn("Path to keyStore for SSL Client-Authentication is empty or null");
- throw new EAAFConfigurationException("Path to keyStore for SSL Client-Authentication is empty or null", new Object[] {});
-
- }
-
- } catch (final KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) {
- log.warn("Can NOT read keyStore: {} from filesystem", localKeyStorePath, null, e);
- throw new EAAFConfigurationException("Can NOT read keyStore: {} from filesystem", new Object[] {localKeyStorePath}, e);
-
- }
-
- }
-
- private LayeredConnectionSocketFactory getSSLContext(ClientAuthMode clientAuthMode) {
- SSLContext sslContext = null;
- try {
- if (clientAuthMode.equals(ClientAuthMode.SSL)) {
- sslContext = buildSSLContextWithSSLClientAuthentication();
-
- } else {
- log.trace("Initializing default SSL Context ... ");
- sslContext = SSLContext.getDefault();
-
- }
-
- //set hostname verifier
- HostnameVerifier hostnameVerifier = null;
- if (basicConfig.getBasicConfigurationBoolean(
- PROP_CONFIG_CLIENT_HTTP_SSL_HOSTNAMEVERIFIER_TRUSTALL,
- false)) {
- hostnameVerifier = new NoopHostnameVerifier();
- log.warn("HTTP client-builder deactivates SSL Host-name verification!");
-
- }
-
- final LayeredConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext , hostnameVerifier);
-
- return sslSocketFactory;
-
- } catch (final NoSuchAlgorithmException | KeyManagementException | UnrecoverableKeyException | KeyStoreException | EAAFConfigurationException e) {
- log.warn("HTTP client-builder can NOT initialze SSL-Context", e);
-
- }
-
- log.info("HTTP client-builder successfuly initialized");
- return null;
-
- }
-
- private void injectConnectionPoolIfRequired(LayeredConnectionSocketFactory sslConnectionFactory) {
- if (basicConfig.getBasicConfigurationBoolean(
- PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_USE,
- true)) {
- PoolingHttpClientConnectionManager pool;
-
- //set socketFactoryRegistry if SSLConnectionFactory is Set
- if (sslConnectionFactory != null) {
- final Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
- .register("http", PlainConnectionSocketFactory.getSocketFactory())
- .register("https", sslConnectionFactory)
- .build();
- log.trace("Inject SSLSocketFactory into pooled connection");
- pool = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
-
- } else {
- pool = new PoolingHttpClientConnectionManager();
-
- }
-
- pool.setDefaultMaxPerRoute(Integer.valueOf(basicConfig.getBasicConfiguration(
- PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXPERROUTE,
- DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXPERROUTE)));
- pool.setMaxTotal(Integer.valueOf(basicConfig.getBasicConfiguration(
- PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXTOTAL,
- DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXTOTAL)));
-
- httpClientBuilder.setConnectionManager(pool);
- log.debug("Initalize http-client pool with, maxTotal: {} maxPerRoute: {}", pool.getMaxTotal(), pool.getDefaultMaxPerRoute());
-
- } else if (sslConnectionFactory != null) {
- log.trace("Inject SSLSocketFactory without connection pool");
- httpClientBuilder.setSSLSocketFactory(sslConnectionFactory );
-
- }
-
-
- }
-
-
-
+ private static final Logger log = LoggerFactory.getLogger(HttpClientFactory.class);
+ @Autowired(required = true)
+ private IConfiguration basicConfig;
+ @Autowired(required = true)
+ ResourceLoader resourceLoader;
+
+ public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_USE =
+ "client.http.connection.pool.use";
+ public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXTOTAL =
+ "client.http.connection.pool.maxtotal";
+ public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXPERROUTE =
+ "client.http.connection.pool.maxperroute";
+ public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET =
+ "client.http.connection.timeout.socket";
+ public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION =
+ "client.http.connection.timeout.connection";
+ public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_REQUEST =
+ "client.http.connection.timeout.request";
+ public static final String PROP_CONFIG_CLIENT_HTTP_SSL_HOSTNAMEVERIFIER_TRUSTALL =
+ "client.http.ssl.hostnameverifier.trustall";
+
+ public static final String PROP_CONFIG_CLIENT_MODE = "client.authmode";
+ public static final String PROP_CONFIG_CLIENT_AUTH_HTTP_USERNAME = "client.auth.http.username";
+ public static final String PROP_CONFIG_CLIENT_AUTH_HTTP_PASSORD = "client.auth.http.password";
+ public static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_PATH =
+ "client.auth.ssl.keystore.path";
+ public static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_PASSORD =
+ "client.auth.ssl.keystore.password";
+ public static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_TYPE =
+ "client.auth.ssl.keystore.type";
+ public static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEY_PASSWORD =
+ "client.auth.ssl.key.password";
+ public static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEY_ALIAS = "client.auth.ssl.key.alias";
+
+ // default configuration values
+ public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET = "15";
+ public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION = "15";
+ public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_REQUEST = "30";
+ public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXTOTAL = "500";
+ public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXPERROUTE = "100";
+
+ public enum ClientAuthMode {
+ NONE("none"), PASSWORD("password"), SSL("ssl");
+
+ private final String mode;
+
+ private ClientAuthMode(final String mode) {
+ this.mode = mode;
+ }
+
+ /**
+ * Get the PVP mode.
+ *
+ * @return
+ */
+ public String getMode() {
+ return this.mode;
+ }
+
+ /**
+ * Get http-client authentication mode from String representation.
+ *
+ * @param s Config parameter
+ * @return
+ */
+ public static ClientAuthMode fromString(final String s) {
+ try {
+ return ClientAuthMode.valueOf(s.toUpperCase());
+
+ } catch (IllegalArgumentException | NullPointerException e) {
+ return null;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return getMode();
+
+ }
+
+ }
+
+ public enum KeyStoreType {
+ PKCS12("pkcs12"), JKS("jks");
+
+ private final String type;
+
+ private KeyStoreType(final String type) {
+ this.type = type;
+ }
+
+ /**
+ * Get the KeyStore type.
+ *
+ * @return
+ */
+ public String getType() {
+ return this.type;
+ }
+
+ /**
+ * Get Keystore type from configuration.
+ *
+ * @param s String representation for keyStore type
+ * @return
+ */
+ public static KeyStoreType fromString(final String s) {
+ try {
+ return KeyStoreType.valueOf(s.toUpperCase());
+
+ } catch (IllegalArgumentException | NullPointerException e) {
+ return null;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return getType();
+
+ }
+
+ }
+
+ private HttpClientBuilder httpClientBuilder = null;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egiz.eaaf.core.impl.utils.IHttpClientFactory#getHttpClient()
+ */
+ @Override
+ public CloseableHttpClient getHttpClient() {
+ return getHttpClient(true);
+
+ }
+
+ @Override
+ public CloseableHttpClient getHttpClient(final boolean followRedirects) {
+ RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
+ if (!followRedirects) {
+ redirectStrategy = new RedirectStrategy() {
+
+ @Override
+ public boolean isRedirected(final HttpRequest request, final HttpResponse response,
+ final HttpContext context) throws ProtocolException {
+ return false;
+ }
+
+ @Override
+ public HttpUriRequest getRedirect(final HttpRequest request, final HttpResponse response,
+ final HttpContext context) throws ProtocolException {
+ return null;
+ }
+ };
+ }
+
+ return httpClientBuilder.setRedirectStrategy(redirectStrategy).build();
+
+ }
+
+ @PostConstruct
+ private void initalize() {
+ // initialize http client
+ log.trace("Initializing HTTP Client-builder ... ");
+ httpClientBuilder = HttpClients.custom();
+
+ // set default request configuration
+ final RequestConfig requestConfig =
+ RequestConfig.custom()
+ .setConnectTimeout(
+ Integer.parseInt(basicConfig.getBasicConfiguration(
+ PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION,
+ DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION)) * 1000)
+ .setConnectionRequestTimeout(Integer.parseInt(basicConfig.getBasicConfiguration(
+ PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_REQUEST,
+ DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_REQUEST)) * 1000)
+ .setSocketTimeout(Integer.parseInt(
+ basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET,
+ DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET))
+ * 1000)
+ .build();
+ httpClientBuilder.setDefaultRequestConfig(requestConfig);
+
+ ClientAuthMode clientAuthMode = ClientAuthMode.fromString(
+ basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_MODE, ClientAuthMode.NONE.getMode()));
+ if (clientAuthMode == null) {
+ log.warn("Can Not parse ClientAuthMode! Set mode to default value");
+ clientAuthMode = ClientAuthMode.NONE;
+
+ }
+
+ // inject basic http authentication if required
+ log.info("Client authentication-mode is set to: {}", clientAuthMode);
+ injectBasicAuthenticationIfRequired(clientAuthMode);
+
+ // inject authentication if required
+ final LayeredConnectionSocketFactory sslConnectionFactory = getSslContext(clientAuthMode);
+
+ // set pool connection if required
+ injectConnectionPoolIfRequired(sslConnectionFactory);
+
+
+ }
+
+ private void injectBasicAuthenticationIfRequired(final ClientAuthMode clientAuthMode) {
+ if (clientAuthMode.equals(ClientAuthMode.PASSWORD)) {
+ final CredentialsProvider provider = new BasicCredentialsProvider();
+
+ final String username =
+ basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_HTTP_USERNAME);
+ final String password =
+ basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_HTTP_PASSORD);
+
+ if (StringUtils.isEmpty(username)) {
+ log.warn("Http basic authentication was activated but NOT username was set!");
+
+ }
+
+ log.trace("Injecting basic authentication with username: {} and password: {}", username,
+ password);
+ final UsernamePasswordCredentials credentials =
+ new UsernamePasswordCredentials(username, password);
+ provider.setCredentials(AuthScope.ANY, credentials);
+ httpClientBuilder.setDefaultCredentialsProvider(provider);
+ log.info("Basic http authentication was injected with username: {}", username);
+
+ } else {
+ log.trace("Injection of Http Basic authentication was skipped");
+
+ }
+
+ }
+
+ private SSLContext buildSslContextWithSslClientAuthentication()
+ throws KeyManagementException, UnrecoverableKeyException, NoSuchAlgorithmException,
+ KeyStoreException, EaafConfigurationException {
+ log.trace("Injecting SSL client-authentication into http client ... ");
+ final KeyStore keystore = getSslAuthKeyStore();
+ final String keyPasswordString =
+ basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_SSL_KEY_PASSWORD);
+ log.trace("Open SSL Client-Auth keystore with password: {}", keyPasswordString);
+ final char[] keyPassword = (keyPasswordString == null) ? StringUtils.EMPTY.toCharArray()
+ : keyPasswordString.toCharArray();
+ return SSLContexts.custom().loadKeyMaterial(keystore, keyPassword).build();
+
+ }
+
+ private KeyStore getSslAuthKeyStore() throws EaafConfigurationException {
+ final KeyStoreType keyStoreType = KeyStoreType.fromString(basicConfig.getBasicConfiguration(
+ PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_TYPE, KeyStoreType.PKCS12.getType()));
+ final String localKeyStorePath = basicConfig
+ .getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_PATH, StringUtils.EMPTY);
+ final String keyStorePassword = basicConfig
+ .getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_PASSORD, StringUtils.EMPTY);
+
+ try {
+ log.debug("Open keyStore with type: {}", keyStoreType);
+ KeyStore clientStore;
+ if (keyStoreType.equals(KeyStoreType.PKCS12)) {
+ clientStore = KeyStore.getInstance("pkcs12");
+ } else {
+ clientStore = KeyStore.getInstance("JKS");
+ }
+
+
+ log.debug("Read keyStore path: {} from configuration", localKeyStorePath);
+ if (StringUtils.isNotEmpty(localKeyStorePath)) {
+ final String absFilePath = FileUtils.makeAbsoluteUrl(localKeyStorePath,
+ basicConfig.getConfigurationRootDirectory());
+ final Resource ressource = resourceLoader.getResource(absFilePath);
+ final InputStream is = ressource.getInputStream();
+ log.trace("Load keyStore: {} with password: {}", absFilePath, keyStorePassword);
+ clientStore.load(is, keyStorePassword.toCharArray());
+ is.close();
+
+ return clientStore;
+
+ } else {
+ log.warn("Path to keyStore for SSL Client-Authentication is empty or null");
+ throw new EaafConfigurationException(
+ "Path to keyStore for SSL Client-Authentication is empty or null", new Object[] {});
+
+ }
+
+ } catch (final KeyStoreException | NoSuchAlgorithmException | CertificateException
+ | IOException e) {
+ log.warn("Can NOT read keyStore: {} from filesystem", localKeyStorePath, null, e);
+ throw new EaafConfigurationException("Can NOT read keyStore: {} from filesystem",
+ new Object[] {localKeyStorePath}, e);
+
+ }
+
+ }
+
+ private LayeredConnectionSocketFactory getSslContext(final ClientAuthMode clientAuthMode) {
+ SSLContext sslContext = null;
+ try {
+ if (clientAuthMode.equals(ClientAuthMode.SSL)) {
+ sslContext = buildSslContextWithSslClientAuthentication();
+
+ } else {
+ log.trace("Initializing default SSL Context ... ");
+ sslContext = SSLContext.getDefault();
+
+ }
+
+ // set hostname verifier
+ HostnameVerifier hostnameVerifier = null;
+ if (basicConfig.getBasicConfigurationBoolean(
+ PROP_CONFIG_CLIENT_HTTP_SSL_HOSTNAMEVERIFIER_TRUSTALL, false)) {
+ hostnameVerifier = new NoopHostnameVerifier();
+ log.warn("HTTP client-builder deactivates SSL Host-name verification!");
+
+ }
+
+ final LayeredConnectionSocketFactory sslSocketFactory =
+ new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
+
+ return sslSocketFactory;
+
+ } catch (final NoSuchAlgorithmException | KeyManagementException | UnrecoverableKeyException
+ | KeyStoreException | EaafConfigurationException e) {
+ log.warn("HTTP client-builder can NOT initialze SSL-Context", e);
+
+ }
+
+ log.info("HTTP client-builder successfuly initialized");
+ return null;
+
+ }
+
+ private void injectConnectionPoolIfRequired(
+ final LayeredConnectionSocketFactory sslConnectionFactory) {
+ if (basicConfig.getBasicConfigurationBoolean(PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_USE,
+ true)) {
+ PoolingHttpClientConnectionManager pool;
+
+ // set socketFactoryRegistry if SSLConnectionFactory is Set
+ if (sslConnectionFactory != null) {
+ final Registry<ConnectionSocketFactory> socketFactoryRegistry =
+ RegistryBuilder.<ConnectionSocketFactory>create()
+ .register("http", PlainConnectionSocketFactory.getSocketFactory())
+ .register("https", sslConnectionFactory).build();
+ log.trace("Inject SSLSocketFactory into pooled connection");
+ pool = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
+
+ } else {
+ pool = new PoolingHttpClientConnectionManager();
+
+ }
+
+ pool.setDefaultMaxPerRoute(Integer.parseInt(
+ basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXPERROUTE,
+ DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXPERROUTE)));
+ pool.setMaxTotal(Integer.parseInt(
+ basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXTOTAL,
+ DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXTOTAL)));
+
+ httpClientBuilder.setConnectionManager(pool);
+ log.debug("Initalize http-client pool with, maxTotal: {} maxPerRoute: {}", pool.getMaxTotal(),
+ pool.getDefaultMaxPerRoute());
+
+ } else if (sslConnectionFactory != null) {
+ log.trace("Inject SSLSocketFactory without connection pool");
+ httpClientBuilder.setSSLSocketFactory(sslConnectionFactory);
+
+ }
+
+
+ }
+
+
+
}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HttpUtils.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HttpUtils.java
new file mode 100644
index 00000000..394d2843
--- /dev/null
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HttpUtils.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria MOA-ID has been developed in a cooperation between
+ * BRZ, the Federal Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at: http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.gv.egiz.eaaf.core.impl.utils;
+
+import javax.servlet.http.HttpServletRequest;
+import org.apache.commons.lang3.StringUtils;
+
+
+
+public class HttpUtils {
+
+
+ /**
+ * Helper method to retrieve server URL including context path.
+ *
+ * @param request HttpServletRequest
+ * @return Server URL including context path (e.g. http://localhost:8443/moa-id-auth
+ */
+ public static String getBaseUrl(final HttpServletRequest request) {
+ final StringBuffer buffer = new StringBuffer(getServerUrl(request));
+
+ // add context path if available
+ final String contextPath = request.getContextPath();
+ if (!StringUtils.isEmpty(contextPath)) {
+ buffer.append(contextPath);
+ }
+
+ return buffer.toString();
+ }
+
+ /**
+ * Helper method to retrieve server URL.
+ *
+ * @param request HttpServletRequest
+ * @return Server URL (e.g. http://localhost:8443)
+ */
+ public static String getServerUrl(final HttpServletRequest request) {
+ final StringBuffer buffer = new StringBuffer();
+
+ // get protocol
+ final String protocol = request.getScheme();
+ buffer.append(protocol).append("://");
+
+ // server name
+ buffer.append(request.getServerName());
+
+ // add port if necessary
+ final int port = request.getServerPort();
+ if ((protocol.equals("http") && port != 80) || (protocol.equals("https") && port != 443)) {
+ buffer.append(':');
+ buffer.append(port);
+ }
+
+ return buffer.toString();
+ }
+
+ /**
+ * Extract the IDP PublicURLPrefix from authrequest.
+ *
+ * @param req HttpServletRequest
+ * @return PublicURLPrefix which ends always without /
+ */
+ public static String extractAuthUrlFromRequest(final HttpServletRequest req) {
+ String authUrl = req.getScheme() + "://" + req.getServerName();
+ if ((req.getScheme().equalsIgnoreCase("https") && req.getServerPort() != 443)
+ || (req.getScheme().equalsIgnoreCase("http") && req.getServerPort() != 80)) {
+ authUrl = authUrl.concat(":" + req.getServerPort());
+ }
+ authUrl = authUrl.concat(req.getContextPath());
+ return authUrl;
+
+ }
+
+ /**
+ * Extract the IDP requested URL from authrequest.
+ *
+ * @param req HttpServletRequest
+ * @return RequestURL which ends always without /
+ */
+ public static String extractAuthServletPathFromRequest(final HttpServletRequest req) {
+ return extractAuthUrlFromRequest(req).concat(req.getServletPath());
+
+ }
+
+ /**
+ * Add a http GET parameter to URL.
+ *
+ * @param url URL
+ * @param paramname Name of the parameter.
+ * @param paramvalue Value of the parameter.
+ * @return
+ */
+ public static String addUrlParameter(final String url, final String paramname,
+ final String paramvalue) {
+ final String param = paramname + "=" + paramvalue;
+ if (url.indexOf("?") < 0) {
+ return url + "?" + param;
+ } else {
+ return url + "&" + param;
+ }
+ }
+
+}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/IHttpClientFactory.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/IHttpClientFactory.java
index 1975fb52..0dc00573 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/IHttpClientFactory.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/IHttpClientFactory.java
@@ -4,18 +4,19 @@ import org.apache.http.impl.client.CloseableHttpClient;
public interface IHttpClientFactory {
- /**
- * Return an instance of a Apache HTTP client that follows http redirects automatically
- *
- * @return
- */
- CloseableHttpClient getHttpClient();
+ /**
+ * Return an instance of a Apache HTTP client that follows http redirects automatically.
+ *
+ * @return
+ */
+ CloseableHttpClient getHttpClient();
- /**
- * Return an instance of a Apache HTTP client
- * @param followRedirects
- * @return
- */
- CloseableHttpClient getHttpClient(boolean followRedirects);
-
-} \ No newline at end of file
+ /**
+ * Return an instance of a Apache HTTP client.
+ *
+ * @param followRedirects if <code>false</code>, the client does not flow 30x http redirects
+ * @return
+ */
+ CloseableHttpClient getHttpClient(boolean followRedirects);
+
+}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyStoreUtils.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyStoreUtils.java
index e3d74066..18ddf422 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyStoreUtils.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyStoreUtils.java
@@ -1,36 +1,28 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
package at.gv.egiz.eaaf.core.impl.utils;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
@@ -42,27 +34,27 @@ import java.security.cert.CertificateFactory;
/**
* Utility for creating and loading key stores.
- *
+ *
* @author Paul Ivancsics
* @version $Id$
*/
public class KeyStoreUtils {
-
- /**
- * JAVA KeyStore
- */
- private static final String KEYSTORE_TYPE_JKS = "JKS";
-
- /**
- * PKCS12 KeyStore
- */
- private static final String KEYSTORE_TYPE_PKCS12 = "PKCS12";
-
-
+
+ /**
+ * JAVA KeyStore.
+ */
+ private static final String KEYSTORE_TYPE_JKS = "JKS";
+
+ /**
+ * PKCS12 KeyStore.
+ */
+ private static final String KEYSTORE_TYPE_PKCS12 = "PKCS12";
+
+
/**
* Loads a key store from file.
- *
+ *
* @param keystoreType key store type
* @param urlString URL of key store
* @param password password protecting the key store
@@ -70,20 +62,35 @@ public class KeyStoreUtils {
* @throws IOException thrown while reading the key store from file
* @throws GeneralSecurityException thrown while creating the key store
*/
- public static KeyStore loadKeyStore(
- String keystoreType,
- String urlString,
- String password)
- throws IOException, GeneralSecurityException {
-
- URL keystoreURL = new URL(urlString);
- InputStream in = keystoreURL.openStream();
+ public static KeyStore loadKeyStore(final String keystoreType, final String urlString,
+ final String password) throws IOException, GeneralSecurityException {
+
+ final URL keystoreUrl = new URL(urlString);
+ final InputStream in = keystoreUrl.openStream();
return loadKeyStore(keystoreType, in, password);
}
+
/**
- * Loads a key store from an <code>InputStream</code>, and
- * closes the <code>InputStream</code>.
- *
+ * Load a KeyStore from Filesystem.
+ *
+ * @param keyStorePath Path to KeyStore
+ * @param password KeyStore password
+ * @return KeyStore
+ * @throws KeyStoreException In case of a keystore error
+ * @throws IOException In case of a general read error
+ */
+ public static KeyStore loadKeyStore(final String keyStorePath, final String password)
+ throws KeyStoreException, IOException {
+ final URL keystoreUrl = new URL(keyStorePath);
+ final InputStream in = keystoreUrl.openStream();
+ final InputStream isBuffered = new BufferedInputStream(in);
+ return loadKeyStore(isBuffered, password);
+
+ }
+
+ /**
+ * Loads a key store from an <code>InputStream</code>, and closes the <code>InputStream</code>.
+ *
* @param keystoreType key store type
* @param in input stream
* @param password password protecting the key store
@@ -91,39 +98,63 @@ public class KeyStoreUtils {
* @throws IOException thrown while reading the key store from the stream
* @throws GeneralSecurityException thrown while creating the key store
*/
- public static KeyStore loadKeyStore(
- String keystoreType,
- InputStream in,
- String password)
- throws IOException, GeneralSecurityException {
+ public static KeyStore loadKeyStore(final String keystoreType, final InputStream in,
+ final String password) throws IOException, GeneralSecurityException {
char[] chPassword = null;
- if (password != null)
+ if (password != null) {
chPassword = password.toCharArray();
- KeyStore ks = KeyStore.getInstance(keystoreType);
+ }
+ final KeyStore ks = KeyStore.getInstance(keystoreType);
ks.load(in, chPassword);
in.close();
return ks;
}
+
/**
- * Creates a key store from X509 certificate files, aliasing them with
- * the index in the <code>String[]</code>, starting with <code>"0"</code>.
- *
+ * Loads a keyStore without knowing the keyStore type.
+ *
+ * @param is input stream
+ * @param password Password protecting the keyStore
+ * @return keyStore loaded
+ * @throws KeyStoreException thrown if keyStore cannot be loaded
+ * @throws IOException In case of a general error
+ */
+ public static KeyStore loadKeyStore(final InputStream is, final String password)
+ throws KeyStoreException, IOException {
+ is.mark(1024 * 1024);
+ KeyStore ks = null;
+ try {
+ try {
+ ks = loadKeyStore(KEYSTORE_TYPE_PKCS12, is, password);
+ } catch (final IOException e2) {
+ is.reset();
+ ks = loadKeyStore(KEYSTORE_TYPE_JKS, is, password);
+ }
+ } catch (final Exception e) {
+ e.printStackTrace();
+
+ }
+ return ks;
+
+ }
+
+ /**
+ * Creates a key store from X509 certificate files, aliasing them with the index in the
+ * <code>String[]</code>, starting with <code>"0"</code>.
+ *
* @param keyStoreType key store type
* @param certFilenames certificate filenames
* @return key store created
- * @throws IOException thrown while reading the certificates from file
- * @throws GeneralSecurityException thrown while creating the key store
+ * @throws Exception In case of an error
*/
- public static KeyStore createKeyStore(
- String keyStoreType,
- String[] certFilenames)
- throws IOException, GeneralSecurityException {
+ public static KeyStore createKeyStore(final String keyStoreType, final String[] certFilenames)
+ throws Exception {
- KeyStore ks = KeyStore.getInstance(keyStoreType);
+ final KeyStore ks = KeyStore.getInstance(keyStoreType);
ks.load(null, null);
for (int i = 0; i < certFilenames.length; i++) {
- Certificate cert = loadCertificate(certFilenames[i]);
+ final Certificate cert = loadCertificate(certFilenames[i]);
ks.setCertificateEntry("" + i, cert);
}
return ks;
@@ -131,69 +162,36 @@ public class KeyStoreUtils {
/**
* Loads an X509 certificate from file.
+ *
* @param certFilename filename
* @return the certificate loaded
- * @throws IOException thrown while reading the certificate from file
- * @throws GeneralSecurityException thrown while creating the certificate
+ * @throws Exception In case of an IO exception
*/
- private static Certificate loadCertificate(String certFilename)
- throws IOException, GeneralSecurityException {
+ private static Certificate loadCertificate(final String certFilename)
+ throws Exception {
+ FileInputStream in = null;
+ try {
+ in = new FileInputStream(certFilename);
+ final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
+ final Certificate cert = certFactory.generateCertificate(in);
+ in.close();
+ return cert;
- FileInputStream in = new FileInputStream(certFilename);
- CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
- Certificate cert = certFactory.generateCertificate(in);
- in.close();
- return cert;
+ } catch (final Exception e) {
+ throw e;
+
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (final IOException e) {
+ e.printStackTrace();
+ }
+
+ }
+ }
}
-
-
- /**
- * Loads a keyStore without knowing the keyStore type
- * @param keyStorePath URL to the keyStore
- * @param password Password protecting the keyStore
- * @return keyStore loaded
- * @throws KeyStoreException thrown if keyStore cannot be loaded
- * @throws FileNotFoundException
- * @throws IOException
- */
- public static KeyStore loadKeyStore(String keyStorePath, String password) throws KeyStoreException, IOException{
-
- //InputStream is = new FileInputStream(keyStorePath);
- URL keystoreURL = new URL(keyStorePath);
- InputStream in = keystoreURL.openStream();
- InputStream isBuffered = new BufferedInputStream(in);
- return loadKeyStore(isBuffered, password);
-
- }
-
- /**
- * Loads a keyStore without knowing the keyStore type
- * @param in input stream
- * @param password Password protecting the keyStore
- * @return keyStore loaded
- * @throws KeyStoreException thrown if keyStore cannot be loaded
- * @throws FileNotFoundException
- * @throws IOException
- */
-public static KeyStore loadKeyStore(InputStream is, String password) throws KeyStoreException, IOException{
- is.mark(1024*1024);
- KeyStore ks = null;
- try {
- try {
- ks = loadKeyStore(KEYSTORE_TYPE_PKCS12, is, password);
- } catch (IOException e2) {
- is.reset();
- ks = loadKeyStore(KEYSTORE_TYPE_JKS, is, password);
- }
- } catch(Exception e) {
- e.printStackTrace();
-
- }
- return ks;
-
- }
-
-
+
}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyValueUtils.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyValueUtils.java
index e753f19f..929d2994 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyValueUtils.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyValueUtils.java
@@ -1,29 +1,22 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.core.impl.utils;
import java.util.ArrayList;
@@ -35,341 +28,347 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
-
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
+ * Utils to operate on Key/Value based configurations.
+ *
* @author tlenz
*
*/
public class KeyValueUtils {
- private static final Logger log = LoggerFactory.getLogger(KeyValueUtils.class);
-
- public static final String KEY_DELIMITER = ".";
- public static final String CSV_DELIMITER = ",";
- public static final String KEYVVALUEDELIMITER = "=";
- public static final String DEFAULT_VALUE = "default";
-
- /**
- * Convert Java properties into a Map<String, String>
- * <br><br>
- * <b>Important:</b> The key/values from properties must be of type String!
- *
- * @param properties
- * @return
- */
- public static Map<String, String> convertPropertiesToMap(Properties properties) {
- return new HashMap<String, String>((Map) properties);
-
- //INFO Java8 solution ;)
-// return properties.entrySet().stream().collect(
-// Collectors.toMap(
-// e -> e.getKey().toString(),
-// e -> e.getValue().toString()
-// )
-// );
-
- }
-
- /**
- * Extract the first child of an input key after a the prefix
- *
- * @param key Full input key
- * @param prefix Prefix
- * @return Child key {String} if it exists or null
- */
- public static String getFirstChildAfterPrefix(String key, String prefix) {
- final String idAfterPrefix = removePrefixFromKey(key, prefix);
- if (idAfterPrefix != null) {
- final int index = idAfterPrefix.indexOf(KEY_DELIMITER);
- if (index > 0) {
- final String adding = idAfterPrefix.substring(0, index);
- if (!(adding.isEmpty())) {
- return adding;
-
- }
- } else if (!(idAfterPrefix.isEmpty())) {
- return idAfterPrefix;
-
- }
-
- }
- return null;
- }
-
- /**
- * Extract the prefix from an input key
- *
- * @param key Full input key
- * @param suffix Suffix of this key
- * @return Prefix {String} of the key or null if input key does not ends with postfix string
- */
- public static String getPrefixFromKey(String key, String suffix) {
- if (key != null && suffix != null && key.endsWith(suffix)) {
- final String idPreforeSuffix = key.substring(0, key.length()-suffix.length());
- if (idPreforeSuffix.endsWith(KEY_DELIMITER))
- return idPreforeSuffix.substring(0, idPreforeSuffix.length()-1);
- else
- return idPreforeSuffix;
- }
- return null;
-
- }
-
- /**
- * Remove a prefix string from a key
- *
- * @param key Full input key
- * @param prefix Prefix, which should be removed
- * @return The suffix of the input key or null if the input does not starts with the prefix
- */
- public static String removePrefixFromKey(String key, String prefix) {
- if (prefix == null)
- prefix = new String();
-
- if (key!=null && key.startsWith(prefix)) {
- String afterPrefix = key.substring(prefix.length());
- final int index = afterPrefix.indexOf(KEY_DELIMITER);
-
- if (index == 0) {
- afterPrefix = afterPrefix.substring(1);
-
- }
- return afterPrefix;
-
- }
- return null;
- }
-
- /**
- * Remove a prefix string from all keys in {Map<String, String>} of key/value pairs
- *
- * @param keys Input data of key/value pairs
- * @param prefix Prefix which should be removed
- * @return {Map<String, String>} of key/value pairs without prefix in key, but never null
- */
- public static Map<String, String> removePrefixFromKeys(Map<String, String> keys, String prefix) {
- final Map<String, String> result = new HashMap<String, String>();
- final Iterator<Entry<String, String>> interator = keys.entrySet().iterator();
- while(interator.hasNext()) {
- final Entry<String, String> el = interator.next();
- final String newKey = removePrefixFromKey(el.getKey(), prefix);
- if (StringUtils.isNotEmpty(newKey)) {
- result.put(newKey, el.getValue());
- }
- }
-
- return result;
- }
-
- /**
- * Get a subset of key/value pairs which starts with a prefix string
- * The Prefix is removed from the key
- *
- * @param keys Input data of key/value pairs
- * @param prefix Prefix string
- * @return {Map<String, String>} of key/value pairs without prefix in key, but never null
- */
- public static Map<String, String> getSubSetWithPrefix(Map<String, String> keys, String prefix) {
- return removePrefixFromKeys(keys, prefix);
- }
-
-
- /**
- * Add a prefix to key/value pairs to make the key absolute according to key namespace convention
- *
- * @param input Input key/value pairs which should be updated
- * @param prefix Key prefix, which should be added if the key is not absolute
- * @param absolutIdentifier Key identifier, which indicates an absolute key
- * @return {Map<String, String>} of key/value pairs in which all keys are absolute but never null
- */
- public static Map<String, String> makeKeysAbsolut(Map<String, String> input, String prefix, String absolutIdentifier) {
- final Map<String, String> result = new HashMap<String, String>();
- final Iterator<Entry<String, String>> interator = input.entrySet().iterator();
- while(interator.hasNext()) {
- final Entry<String, String> el = interator.next();
- if (!el.getKey().startsWith(absolutIdentifier)) {
- //key is not absolute -> add prefix
- result.put(prefix
- + KEY_DELIMITER
- + el.getKey(),
- el.getValue());
-
- } else {
- //key is absolute
- result.put(el.getKey(), el.getValue());
- }
- }
- return result;
- }
-
- /**
- * Get the parent key string from an input key
- *
- * @param key input key
- * @return parent key or the empty String if no parent exists
- */
- public static String getParentKey(String key) {
- if (StringUtils.isNotEmpty(key)) {
- final int index = key.lastIndexOf(KEY_DELIMITER);
- if (index > 0) {
- return key.substring(0, index);
-
- }
- }
-
- return new String();
- }
-
- /**
- * Find the highest free list counter
- *
- * @param input Array of list keys
- * @param listPrefix {String} prefix of the list
- * @return {int} highest free list counter
- */
- public static int findNextFreeListCounter(String[] input,
- String listPrefix) {
- final List<Integer> counters = new ArrayList<Integer>();
- if (input == null || input.length == 0)
- return 0;
-
- else {
- for (final String key : input) {
- final String listIndex = getFirstChildAfterPrefix(key, listPrefix);
- counters.add(Integer.parseInt(listIndex));
-
- }
- Collections.sort(counters);
- return counters.get(counters.size()-1) + 1;
- }
- }
-
- /**
- * Find the highest free list counter
- *
- * @param keySet {Set<String>} of list keys
- * @param listPrefix {String} prefix of the list
- * @return {int} highest free list counter
- */
- public static int findNextFreeListCounter(Set<String> keySet,
- String listPrefix) {
- if (keySet.isEmpty())
- return 0;
-
- final String[] array = new String[keySet.size()];
- keySet.toArray(array);
- return findNextFreeListCounter(array, listPrefix);
- }
-
-
- /**
- * Normalize a CSV encoded list of value of an key/value pair
- *
- * This method removes all whitespace at the begin or the
- * end of CSV values and remove newLine signs at the end of value.
- * The ',' is used as list delimiter
- *
- * @param value CSV encoded input data
- * @return normalized CSV encoded data or null if {value} is null or empty
- */
- public static String normalizeCSVValueString(String value) {
- String normalizedCodes = null;
- if (StringUtils.isNotEmpty(value)) {
- final String[] codes = value.split(CSV_DELIMITER);
- for (final String el: codes) {
- if (normalizedCodes == null)
- normalizedCodes = StringUtils.chomp(el.trim());
- else
- normalizedCodes += "," + StringUtils.chomp(el.trim());
-
- }
- }
- return normalizedCodes;
- }
-
-
- /**
- * Check a String if it is a comma separated list of values
- *
- * This method uses the ',' as list delimiter.
- *
- * @param value CSV encoded input data
- * @return true if the input data contains a ',' and has more then 1 list element, otherwise false
- */
- public static boolean isCSVValueString(String value) {
- if (StringUtils.isNotEmpty(value)) {
- final String[] codes = value.split(CSV_DELIMITER);
- if (codes.length >= 2) {
- if (StringUtils.isNotEmpty(codes[1].trim()))
- return true;
-
- }
- }
-
- return false;
- }
-
- /**
- * Convert a CSV list to a List of CSV values
- * <br><br>
- * This method removes all whitespace at the begin or the
- * end of CSV values and remove newLine signs at the end of value.
- * The ',' is used as list delimiter
- *
- * @param csv CSV encoded input data
- * @return List of CSV normalized values, but never null
- */
- @Nonnull
- public static List<String> getListOfCSVValues(@Nullable String csv) {
- final List<String> list = new ArrayList<String>();
- if (StringUtils.isNotEmpty(csv)) {
- final String[] values = csv.split(CSV_DELIMITER);
- for (final String el: values)
- list.add(el.trim());
-
- }
-
- return list;
- }
-
- /**
- * Convert a List of String elements to a Map of Key/Value pairs
- * <br>
- * Every List element used as a key/value pair and the '=' sign represents the delimiter between key and value
- *
- * @param elements List of key/value elements
- * @return Map of Key / Value pairs, but never null
- */
- public static Map<String, String> convertListToMap(List<String> elements) {
- final Map<String, String> map = new HashMap<String, String>();
- for (final String el : elements) {
- if (el.contains(KEYVVALUEDELIMITER)) {
- final String[] split = el.split(KEYVVALUEDELIMITER);
- map.put(split[0], split[1]);
-
- } else
- log.debug("Key/Value Mapper: '" + el + "' contains NO '='. Ignore it.");
-
- }
-
- return map;
- }
-
- /**
- * This method remove all newline delimiter (\n or \r\n) from input data
- *
- * @param value Input String
- * @return Input String without newline characters
- */
- public static String removeAllNewlineFromString(String value) {
- return value.replaceAll("(\\t|\\r?\\n)+", "");
-
- }
-
+ private static final Logger log = LoggerFactory.getLogger(KeyValueUtils.class);
+
+ public static final String KEY_DELIMITER = ".";
+ public static final String CSV_DELIMITER = ",";
+ public static final String KEYVVALUEDELIMITER = "=";
+ public static final String DEFAULT_VALUE = "default";
+
+ /**
+ * Convert Java properties into a Map String/String.
+ * <br>
+ * <b>Important:</b> The key/values from properties must be of type String!
+ *
+ * @param properties Java {@link Properties} that should be converted
+ * @return
+ */
+ public static Map<String, String> convertPropertiesToMap(final Properties properties) {
+ return new HashMap<String, String>((Map) properties);
+
+ // INFO Java8 solution ;)
+ // return properties.entrySet().stream().collect(
+ // Collectors.toMap(
+ // e -> e.getKey().toString(),
+ // e -> e.getValue().toString()
+ // )
+ // );
+
+ }
+
+ /**
+ * Extract the first child of an input key after a the prefix.
+ *
+ * @param key Full input key
+ * @param prefix Prefix
+ * @return Child key {String} if it exists or null
+ */
+ public static String getFirstChildAfterPrefix(final String key, final String prefix) {
+ final String idAfterPrefix = removePrefixFromKey(key, prefix);
+ if (idAfterPrefix != null) {
+ final int index = idAfterPrefix.indexOf(KEY_DELIMITER);
+ if (index > 0) {
+ final String adding = idAfterPrefix.substring(0, index);
+ if (!(adding.isEmpty())) {
+ return adding;
+
+ }
+ } else if (!(idAfterPrefix.isEmpty())) {
+ return idAfterPrefix;
+
+ }
+
+ }
+ return null;
+ }
+
+ /**
+ * Extract the prefix from an input key.
+ *
+ * @param key Full input key
+ * @param suffix Suffix of this key
+ * @return Prefix {String} of the key or null if input key does not ends with postfix string
+ */
+ public static String getPrefixFromKey(final String key, final String suffix) {
+ if (key != null && suffix != null && key.endsWith(suffix)) {
+ final String idPreforeSuffix = key.substring(0, key.length() - suffix.length());
+ if (idPreforeSuffix.endsWith(KEY_DELIMITER)) {
+ return idPreforeSuffix.substring(0, idPreforeSuffix.length() - 1);
+ } else {
+ return idPreforeSuffix;
+ }
+ }
+ return null;
+
+ }
+
+ /**
+ * Remove a prefix string from a key.
+ *
+ * @param key Full input key
+ * @param prefix Prefix, which should be removed
+ * @return The suffix of the input key or null if the input does not starts with the prefix
+ */
+ public static String removePrefixFromKey(final String key, String prefix) {
+ if (prefix == null) {
+ prefix = StringUtils.EMPTY;
+
+ }
+
+ if (key != null && key.startsWith(prefix)) {
+ String afterPrefix = key.substring(prefix.length());
+ final int index = afterPrefix.indexOf(KEY_DELIMITER);
+
+ if (index == 0) {
+ afterPrefix = afterPrefix.substring(1);
+
+ }
+ return afterPrefix;
+
+ }
+ return null;
+ }
+
+ /**
+ * Remove a prefix string from all keys in Map String/String of key/value pairs.
+ *
+ * @param keys Input data of key/value pairs
+ * @param prefix Prefix which should be removed
+ * @return Map String/String of key/value pairs without prefix in key, but never null
+ */
+ public static Map<String, String> removePrefixFromKeys(final Map<String, String> keys,
+ final String prefix) {
+ final Map<String, String> result = new HashMap<>();
+ final Iterator<Entry<String, String>> interator = keys.entrySet().iterator();
+ while (interator.hasNext()) {
+ final Entry<String, String> el = interator.next();
+ final String newKey = removePrefixFromKey(el.getKey(), prefix);
+ if (StringUtils.isNotEmpty(newKey)) {
+ result.put(newKey, el.getValue());
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Get a subset of key/value pairs which starts with a prefix string The Prefix is removed from
+ * the key.
+ *
+ * @param keys Input data of key/value pairs
+ * @param prefix Prefix string
+ * @return Map String/String of key/value pairs without prefix in key, but never null
+ */
+ public static Map<String, String> getSubSetWithPrefix(final Map<String, String> keys,
+ final String prefix) {
+ return removePrefixFromKeys(keys, prefix);
+ }
+
+
+ /**
+ * Add a prefix to key/value pairs to make the key absolute according to key namespace convention.
+ *
+ * @param input Input key/value pairs which should be updated
+ * @param prefix Key prefix, which should be added if the key is not absolute
+ * @param absolutIdentifier Key identifier, which indicates an absolute key
+ * @return Map String/String of key/value pairs in which all keys are absolute but never null
+ */
+ public static Map<String, String> makeKeysAbsolut(final Map<String, String> input,
+ final String prefix, final String absolutIdentifier) {
+ final Map<String, String> result = new HashMap<>();
+ final Iterator<Entry<String, String>> interator = input.entrySet().iterator();
+ while (interator.hasNext()) {
+ final Entry<String, String> el = interator.next();
+ if (!el.getKey().startsWith(absolutIdentifier)) {
+ // key is not absolute -> add prefix
+ result.put(prefix + KEY_DELIMITER + el.getKey(), el.getValue());
+
+ } else {
+ // key is absolute
+ result.put(el.getKey(), el.getValue());
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Get the parent key string from an input key.
+ *
+ * @param key input key
+ * @return parent key or the empty String if no parent exists
+ */
+ public static String getParentKey(final String key) {
+ if (StringUtils.isNotEmpty(key)) {
+ final int index = key.lastIndexOf(KEY_DELIMITER);
+ if (index > 0) {
+ return key.substring(0, index);
+
+ }
+ }
+
+ return StringUtils.EMPTY;
+ }
+
+ /**
+ * Find the highest free list counter.
+ *
+ * @param input Array of list keys
+ * @param listPrefix {String} prefix of the list
+ * @return {int} highest free list counter
+ */
+ public static int findNextFreeListCounter(final String[] input, final String listPrefix) {
+ final List<Integer> counters = new ArrayList<>();
+ if (input == null || input.length == 0) {
+ return 0;
+ } else {
+ for (final String key : input) {
+ final String listIndex = getFirstChildAfterPrefix(key, listPrefix);
+ counters.add(Integer.parseInt(listIndex));
+
+ }
+ Collections.sort(counters);
+ return counters.get(counters.size() - 1) + 1;
+ }
+ }
+
+ /**
+ * Find the highest free list counter.
+ *
+ * @param keySet Set of list keys
+ * @param listPrefix {String} prefix of the list
+ * @return {int} highest free list counter
+ */
+ public static int findNextFreeListCounter(final Set<String> keySet, final String listPrefix) {
+ if (keySet.isEmpty()) {
+ return 0;
+ }
+
+ final String[] array = new String[keySet.size()];
+ keySet.toArray(array);
+ return findNextFreeListCounter(array, listPrefix);
+ }
+
+
+ /**
+ * Normalize a CSV encoded list of value of an key/value pair.
+ *
+ * <p>
+ * This method removes all whitespace at the begin or the end of CSV values and remove newLine
+ * signs at the end of value. The ',' is used as list delimiter
+ * </p>
+ *
+ * @param value CSV encoded input data
+ * @return normalized CSV encoded data or null if {value} is null or empty
+ */
+ public static String normalizeCsvValueString(final String value) {
+ String normalizedCodes = null;
+ if (StringUtils.isNotEmpty(value)) {
+ final String[] codes = value.split(CSV_DELIMITER);
+ for (final String el : codes) {
+ if (normalizedCodes == null) {
+ normalizedCodes = StringUtils.chomp(el.trim());
+ } else {
+ normalizedCodes += "," + StringUtils.chomp(el.trim());
+ }
+
+ }
+ }
+ return normalizedCodes;
+ }
+
+
+ /**
+ * Check a String if it is a comma separated list of values.
+ *
+ * <p>
+ * This method uses the ',' as list delimiter.
+ * </p>
+ *
+ * @param value CSV encoded input data
+ * @return true if the input data contains a ',' and has more then 1 list element, otherwise false
+ */
+ public static boolean isCsvValueString(final String value) {
+ if (StringUtils.isNotEmpty(value)) {
+ final String[] codes = value.split(CSV_DELIMITER);
+ if (codes.length >= 2
+ && StringUtils.isNotEmpty(codes[1].trim())) {
+ return true;
+
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Convert a CSV list to a List of CSV values. <br>
+ * <br>
+ * This method removes all whitespace at the begin or the end of CSV values and remove newLine
+ * signs at the end of value. The ',' is used as list delimiter
+ *
+ * @param csv CSV encoded input data
+ * @return List of CSV normalized values, but never null
+ */
+ @Nonnull
+ public static List<String> getListOfCsvValues(@Nullable final String csv) {
+ final List<String> list = new ArrayList<>();
+ if (StringUtils.isNotEmpty(csv)) {
+ final String[] values = csv.split(CSV_DELIMITER);
+ for (final String el : values) {
+ list.add(el.trim());
+ }
+
+ }
+
+ return list;
+ }
+
+ /**
+ * Convert a List of String elements to a Map of Key/Value pairs. <br>
+ * Every List element used as a key/value pair and the '=' sign represents the delimiter between
+ * key and value
+ *
+ * @param elements List of key/value elements
+ * @return Map of Key / Value pairs, but never null
+ */
+ public static Map<String, String> convertListToMap(final List<String> elements) {
+ final Map<String, String> map = new HashMap<>();
+ for (final String el : elements) {
+ if (el.contains(KEYVVALUEDELIMITER)) {
+ final String[] split = el.split(KEYVVALUEDELIMITER);
+ map.put(split[0], split[1]);
+
+ } else {
+ log.debug("Key/Value Mapper: '" + el + "' contains NO '='. Ignore it.");
+ }
+
+ }
+
+ return map;
+ }
+
+ /**
+ * This method remove all newline delimiter (\n or \r\n) from input data.
+ *
+ * @param value Input String
+ * @return Input String without newline characters
+ */
+ public static String removeAllNewlineFromString(final String value) {
+ return value.replaceAll("(\\t|\\r?\\n)+", "");
+
+ }
+
}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/NodeIteratorAdapter.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/NodeIteratorAdapter.java
index ec57b92a..755c4431 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/NodeIteratorAdapter.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/NodeIteratorAdapter.java
@@ -1,92 +1,79 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.core.impl.utils;
import java.util.ListIterator;
-
import org.w3c.dom.DOMException;
import org.w3c.dom.Node;
import org.w3c.dom.traversal.NodeFilter;
import org.w3c.dom.traversal.NodeIterator;
/**
- * A <code>NodeIterator</code> implementation based on a
- * <code>ListIterator</code>.
- *
+ * A <code>NodeIterator</code> implementation based on a <code>ListIterator</code>.
+ *
* @see java.util.ListIterator
* @see org.w3c.dom.traversal.NodeIterator
- *
+ *
*/
public class NodeIteratorAdapter implements NodeIterator {
/** The <code>ListIterator</code> to wrap. */
- private ListIterator nodeIterator;
+ private final ListIterator nodeIterator;
/**
* Create a new <code>NodeIteratorAdapter</code>.
+ *
* @param nodeIterator The <code>ListIterator</code> to iterate over.
*/
- public NodeIteratorAdapter(ListIterator nodeIterator) {
+ public NodeIteratorAdapter(final ListIterator nodeIterator) {
this.nodeIterator = nodeIterator;
}
- /**
- * @see org.w3c.dom.traversal.NodeIterator#getRoot()
- */
+
+ @Override
public Node getRoot() {
return null;
}
- /**
- * @see org.w3c.dom.traversal.NodeIterator#getWhatToShow()
- */
+
+ @Override
public int getWhatToShow() {
return NodeFilter.SHOW_ALL;
}
- /**
- * @see org.w3c.dom.traversal.NodeIterator#getFilter()
- */
+
+ @Override
public NodeFilter getFilter() {
return null;
}
- /**
- * @see org.w3c.dom.traversal.NodeIterator#getExpandEntityReferences()
- */
+
+ @Override
public boolean getExpandEntityReferences() {
return false;
}
- /**
- * @see org.w3c.dom.traversal.NodeIterator#nextNode()
- */
+
+ @Override
public Node nextNode() throws DOMException {
if (nodeIterator.hasNext()) {
return (Node) nodeIterator.next();
@@ -94,9 +81,8 @@ public class NodeIteratorAdapter implements NodeIterator {
return null;
}
- /**
- * @see org.w3c.dom.traversal.NodeIterator#previousNode()
- */
+
+ @Override
public Node previousNode() throws DOMException {
if (nodeIterator.hasPrevious()) {
return (Node) nodeIterator.previous();
@@ -104,10 +90,10 @@ public class NodeIteratorAdapter implements NodeIterator {
return null;
}
- /**
- * @see org.w3c.dom.traversal.NodeIterator#detach()
- */
+
+ @Override
public void detach() {
+
}
}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/NodeListAdapter.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/NodeListAdapter.java
index 69045aaa..a942f75e 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/NodeListAdapter.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/NodeListAdapter.java
@@ -1,68 +1,58 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.core.impl.utils;
import java.util.List;
-
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* A <code>NodeList</code> implementation based on a <code>List</code>.
- *
+ *
* @see java.util.List
* @see org.w3c.dom.NodeList
*/
public class NodeListAdapter implements NodeList {
/** The <code>List</code> to wrap. */
- private List nodeList;
-
+ private final List nodeList;
+
/**
* Create a new <code>NodeListAdapter</code>.
- *
- * @param nodeList The <code>List</code> containing the nodes.
+ *
+ * @param nodeList The <code>List</code> containing the nodes.
*/
- public NodeListAdapter(List nodeList) {
+ public NodeListAdapter(final List nodeList) {
this.nodeList = nodeList;
}
- /**
- * @see org.w3c.dom.NodeList#item(int)
- */
- public Node item(int index) {
+
+ @Override
+ public Node item(final int index) {
return (Node) nodeList.get(index);
}
- /**
- * @see org.w3c.dom.NodeList#getLength()
- */
+
+ @Override
public int getLength() {
return nodeList.size();
}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/Random.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/Random.java
index e236b3a9..14d54b0b 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/Random.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/Random.java
@@ -1,176 +1,188 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+ */
package at.gv.egiz.eaaf.core.impl.utils;
+import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
-
+import at.gv.egiz.eaaf.core.impl.idp.process.support.SecureRandomHolder;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import at.gv.egiz.eaaf.core.impl.idp.process.support.SecureRandomHolder;
-
/**
- * Random number generator used to generate ID's
+ * Random number generator used to generate ID's.
+ *
* @author Paul Ivancsics
* @version $Id$
*/
public class Random {
- private static final Logger log = LoggerFactory.getLogger(Random.class);
-
- private final static char[] allowedPreFix =
- {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
- 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
- private static final DateFormat dateFormater = new SimpleDateFormat("yyyyddMM");
-
- /** random number generator used */
- private static SecureRandom random;
- //private static SeedGenerator seedgenerator;
-
- static {
- try {
- random = SecureRandom.getInstance("SHA256PRNG-FIPS186");
-
- } catch (NoSuchAlgorithmException e) {
- log.warn("Can NOT initialize SecureRandom with: 'SHA256PRNG-FIPS186'. Use 'StrongSecureRandom' as backup");
- random = SecureRandomHolder.getInstance();
-
- }
-
-
- //random = iaik.security.random.SHA256FIPS186Random.getDefault();
- }
-
- /**
- * Generate a unique process reference-value [160bit], which always starts with a letter
- * <br>
- * This unique ID consists of single letter, a 64bit date String[yyyyddMM],
- * and a 88bit random value.
- *
- * @return 160bit ID, which is hex encoded
- */
- public static String nextProcessReferenceValue() {
- //pre-process all three parts of a unique reference value
- String now = dateFormater.format(new Date()); //8 bytes = 64bit
- byte[] randValue = nextByteRandom(11);
- char preFix = allowedPreFix[Math.abs(random.nextInt() % allowedPreFix.length)];
-
- //generate ID
- String returnValue = preFix + new String(Hex.encodeHex(ArrayUtils.addAll(now.getBytes(), randValue))); // 20 bytes = 160 bits
- if (returnValue.length() > 40)
- return returnValue.substring(0, 40);
- else
- return returnValue;
-
- }
-
-
-
- /**
- * Creates a new random number [256bit], and encode it as hex value.
- *
- * @return random hex encoded value [256bit]
- */
- public static String nextHexRandom32() {
- return new String(Hex.encodeHex(nextByteRandom(32))); // 32 bytes = 256 bits
-
- }
-
- /**
- * Creates a new random number [128bit], and encode it as hex value.
- *
- * @return random hex encoded value [128bit]
- */
- public static String nextHexRandom16() {
- return new String(Hex.encodeHex(nextByteRandom(16))); // 16 bytes = 128 bits
-
- }
-
- /**
- * Creates a new random number [64bit], to be used as an ID.
- *
- * @return random long as a String [64bit]
- */
- public static String nextLongRandom() {
- return "".concat(String.valueOf(Math.abs(generateLongRandom(32)))); // 32 bytes = 256 bits
-
- }
-
+ private static final Logger log = LoggerFactory.getLogger(Random.class);
+
+ private static final char[] allowedPreFix =
+ {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
+ 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
+ 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
+
+ /** random number generator used. */
+ private static SecureRandom random;
+ // private static SeedGenerator seedgenerator;
+
+ static {
+ try {
+ random = SecureRandom.getInstance("SHA256PRNG-FIPS186");
+
+ } catch (final NoSuchAlgorithmException e) {
+ log.warn(
+ "Can NOT initialize SecureRandom with: 'SHA256PRNG-FIPS186'. Use 'StrongSecureRandom' as backup");
+ random = SecureRandomHolder.getInstance();
+
+ }
+
+
+ // random = iaik.security.random.SHA256FIPS186Random.getDefault();
+ }
+
+ /**
+ * Generate a unique process reference-value [160bit], which always starts with a letter <br>
+ * This unique ID consists of single letter, a 64bit date String[yyyyddMM], and a 88bit random
+ * value.
+ *
+ * @return 160bit ID, which is hex encoded
+ */
+ public static String nextProcessReferenceValue() {
+ // pre-process all three parts of a unique reference value
+ final DateFormat dateFormater = new SimpleDateFormat("yyyyddMM");
+ final String now = dateFormater.format(new Date()); // 8 bytes = 64bit
+ final byte[] randValue = nextByteRandom(11);
+ final char preFix = allowedPreFix[Math.abs(random.nextInt() % allowedPreFix.length)];
+
+ // generate ID
+ String returnValue;
+ try {
+ returnValue = preFix + new String(Hex.encodeHex(ArrayUtils.addAll(now.getBytes("UTF-8"), randValue)));
+
+ // 20 bytes = 160 bits
+ if (returnValue.length() > 40) {
+ return returnValue.substring(0, 40);
+ } else {
+ return returnValue;
+ }
+
+ } catch (final UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+
+ }
+
+
+
+ }
+
+
+
+ /**
+ * Creates a new random number [256bit], and encode it as hex value.
+ *
+ * @return random hex encoded value [256bit]
+ */
+ public static String nextHexRandom32() {
+ return new String(Hex.encodeHex(nextByteRandom(32))); // 32 bytes = 256 bits
+
+ }
+
+ /**
+ * Creates a new random number [128bit], and encode it as hex value.
+ *
+ * @return random hex encoded value [128bit]
+ */
+ public static String nextHexRandom16() {
+ return new String(Hex.encodeHex(nextByteRandom(16))); // 16 bytes = 128 bits
+
+ }
+
+ /**
+ * Creates a new random number [64bit], to be used as an ID.
+ *
+ * @return random long as a String [64bit]
+ */
+ public static String nextLongRandom() {
+ return "".concat(String.valueOf(Math.abs(generateLongRandom(32)))); // 32 bytes = 256 bits
+
+ }
+
/**
* Creates a new random number, to be used as an ID.
- *
+ *
* @return random long as a String [64bit]
*/
- @Deprecated
- public static String nextRandom() {
- long l = ByteBuffer.wrap(nextByteRandom(32)).getLong(); // 32 bytes = 256 bits
- return "" + Math.abs(l);
-
+ @Deprecated
+ public static String nextRandom() {
+ final long l = ByteBuffer.wrap(nextByteRandom(32)).getLong(); // 32 bytes = 256 bits
+ return "" + Math.abs(l);
+
}
-
-/**
- * Creates a new random byte[]
- *
- * @param size Size of random number in byte
- * @return
- */
-public static byte[] nextBytes(int size) {
- return nextByteRandom(size);
-
-}
-
+
+ /**
+ * Creates a new random byte[].
+ *
+ * @param size Size of random number in byte
+ * @return
+ */
+ public static byte[] nextBytes(final int size) {
+ return nextByteRandom(size);
+
+ }
+
+ /**
+ * initialize random-number generator.
+ */
public static void seedRandom() {
- //TODO: implement reflection on IAIK Seed generator
-// seedgenerator = iaik.security.random.AutoSeedGenerator.getDefault();
-// if (seedgenerator.seedAvailable())
-// random.setSeed(seedgenerator.getSeed());
-
- random.setSeed(System.nanoTime());
+ // TODO: implement reflection on IAIK Seed generator
+ // seedgenerator = iaik.security.random.AutoSeedGenerator.getDefault();
+ // if (seedgenerator.seedAvailable())
+ // random.setSeed(seedgenerator.getSeed());
+
+ random.setSeed(System.nanoTime());
}
-
- private static long generateLongRandom(int size) {
- return ByteBuffer.wrap(nextByteRandom(size)).getLong();
- }
-
+
+ private static long generateLongRandom(final int size) {
+ return ByteBuffer.wrap(nextByteRandom(size)).getLong();
+ }
+
/**
- * Generate a new random number
- *
+ * Generate a new random number.
+ *
* @param size Size of random number in byte
* @return
*/
- private static synchronized byte[] nextByteRandom(int size) {
- byte[] b = new byte[size];
- random.nextBytes(b);
- return b;
-
+ private static synchronized byte[] nextByteRandom(final int size) {
+ final byte[] b = new byte[size];
+ random.nextBytes(b);
+ return b;
+
}
}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SecurePendingRequestIdGenerationStrategy.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SecurePendingRequestIdGenerationStrategy.java
index f0ef9b38..ee88c4bb 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SecurePendingRequestIdGenerationStrategy.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SecurePendingRequestIdGenerationStrategy.java
@@ -1,19 +1,24 @@
package at.gv.egiz.eaaf.core.impl.utils;
import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Arrays;
import java.util.Base64;
-
import javax.annotation.PostConstruct;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
-
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.api.utils.IPendingRequestIdGenerationStrategy;
+import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.exceptions.EaafIllegalStateException;
+import at.gv.egiz.eaaf.core.exceptions.PendingReqIdValidationException;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.DurationFieldType;
@@ -25,190 +30,209 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
-import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
-import at.gv.egiz.eaaf.core.api.utils.IPendingRequestIdGenerationStrategy;
-import at.gv.egiz.eaaf.core.exceptions.EAAFConfigurationException;
-import at.gv.egiz.eaaf.core.exceptions.EAAFException;
-import at.gv.egiz.eaaf.core.exceptions.EAAFIllegalStateException;
-import at.gv.egiz.eaaf.core.exceptions.PendingReqIdValidationException;
-
/**
- * PendingRequestId generation strategy based on signed tokens that facilitates extended token validation
- *
+ * PendingRequestId generation strategy based on signed tokens that facilitates extended token
+ * validation.
+ *
* @author tlenz
*
*/
-public class SecurePendingRequestIdGenerationStrategy implements IPendingRequestIdGenerationStrategy {
- private static final Logger log = LoggerFactory.getLogger(SecurePendingRequestIdGenerationStrategy.class);
-
- @Autowired(required=true) IConfiguration baseConfig;
-
- public static final String CONFIG_PROP_PENDINGREQUESTID_DIGIST_SECRET = "core.pendingrequestid.digist.secret";
- public static final String CONFIG_PROP_PENDINGREQUESTID_DIGIST_ALGORITHM = "core.pendingrequestid.digist.algorithm";
- public static final String CONFIG_PROP_PENDINGREQUESTID_MAX_LIFETIME = "core.pendingrequestid.maxlifetime";
-
- public static final String DEFAULT_PENDINGREQUESTID_DIGIST_ALGORITHM = "HmacSHA256";
- public static final String DEFAULT_PENDINGREQUESTID_MAX_LIFETIME = "300";
-
- private static final int ENCODED_TOKEN_PARTS = 3;
- private static final String TOKEN_SEPARATOR = "|";
- private static final DateTimeFormatter TOKEN_TEXTUAL_DATE_FORMAT =
- DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss SSS");
-
- private int maxPendingRequestIdLifeTime = 300;
- private final int maxPendingReqIdSize = 1024;
- private String digistAlgorithm = null;
- private SecretKey key = null;
- private final byte[] salt = "notRequiredInThisScenario".getBytes();
-
- @Override
- public String generateExternalPendingRequestId() throws EAAFException {
- try {
- final String toSign = buildInternalToken(Random.nextLongRandom(), DateTime.now());
- final StringBuilder externalPendingRequestId= new StringBuilder();
- externalPendingRequestId.append(toSign);
- externalPendingRequestId.append(TOKEN_SEPARATOR);
- externalPendingRequestId.append(Base64.getEncoder().encodeToString(calculateHMAC(toSign)));
- return Base64.getUrlEncoder().encodeToString(externalPendingRequestId.toString().getBytes("UTF-8"));
-
- } catch (final UnsupportedEncodingException e) {
- throw new EAAFException("internal.99", new Object[] {e.getMessage()}, e);
-
- }
-
- }
-
- @Override
- public String getPendingRequestIdWithOutChecks(String externalPendingReqId) throws PendingReqIdValidationException {
- final String[] tokenElements = extractTokens(externalPendingReqId);
- return tokenElements[1];
-
- }
-
- @Override
- public String validateAndGetPendingRequestId(String externalPendingReqId) throws PendingReqIdValidationException {
- try {
- final String[] tokenElements = extractTokens(externalPendingReqId);
- final String internalPendingReqId = tokenElements[1];
- final DateTime timeStamp = TOKEN_TEXTUAL_DATE_FORMAT.parseDateTime(tokenElements[0]);
-
- log.trace("Checking HMAC from externalPendingReqId ... ");
- final byte[] tokenDigest = Base64.getDecoder().decode(tokenElements[2]);
- final byte[] refDigist = calculateHMAC(buildInternalToken(internalPendingReqId, timeStamp));
- if (!Arrays.equals(tokenDigest, refDigist)) {
- log.warn("Digest of Token does NOT match");
- log.debug("Token: {} | Ref: {}", tokenDigest, refDigist);
- throw new PendingReqIdValidationException(null, "Digest of pendingRequestId does NOT match");
-
- }
- log.debug("PendingRequestId HMAC digest check successful");
-
- log.trace("Checking valid period ... ");
- final DateTime now = DateTime.now();
- if (timeStamp.withFieldAdded(
- DurationFieldType.seconds(), maxPendingRequestIdLifeTime).isBefore(now)) {
- log.warn("Token exceeds the valid period");
- log.debug("Token: {} | Now: {}", timeStamp, now );
- throw new PendingReqIdValidationException(internalPendingReqId, "PendingRequestId exceeds the valid period");
-
- }
- log.debug("Token valid-period check successful");
-
- return internalPendingReqId;
-
-
- } catch (final IllegalArgumentException | EAAFIllegalStateException e) {
- log.warn("Token is NOT a valid String. Msg: {}", e.getMessage());
- log.debug("TokenValue: {}", externalPendingReqId);
- throw new PendingReqIdValidationException(null, "PendingReqId is NOT a valid String", e);
-
- }
- }
-
- @NonNull
- private String[] extractTokens(@Nullable String externalPendingReqId) throws PendingReqIdValidationException {
- if (StringUtils.isEmpty(externalPendingReqId)) {
- log.info("PendingReqId is 'null' or empty");
- throw new PendingReqIdValidationException(null, "PendingReqId is 'null' or empty");
-
- }
-
- log.trace("RAW external pendingReqId: {}", externalPendingReqId);
- final byte[] externalPendingReqIdBytes = Base64.getUrlDecoder().decode(externalPendingReqId);
-
- if (externalPendingReqIdBytes.length > maxPendingReqIdSize) {
- log.warn("pendingReqId size exceeds {}", maxPendingReqIdSize);
- throw new PendingReqIdValidationException(null, "pendingReqId exceeds max.size: " + maxPendingReqIdSize);
-
- }
-
- final String stringToken = new String(externalPendingReqIdBytes);
- if (StringUtils.countMatches(stringToken, TOKEN_SEPARATOR) == ENCODED_TOKEN_PARTS - 1) {
- final String[] tokenElements = StringUtils.split(stringToken,
- TOKEN_SEPARATOR, ENCODED_TOKEN_PARTS);
- return tokenElements;
-
- } else {
- log.warn("PendingRequestId has an unvalid format");
- log.debug("PendingRequestId: {}", stringToken);
- throw new PendingReqIdValidationException(null, "PendingReqId has an unvalid format");
-
- }
-
- }
-
-
- @PostConstruct
- private void initialize() throws EAAFConfigurationException {
- log.debug("Initializing " + this.getClass().getName() + " ... ");
-
- final String pendingReqIdDigistSecret = baseConfig.getBasicConfiguration(CONFIG_PROP_PENDINGREQUESTID_DIGIST_SECRET);
- if (StringUtils.isEmpty(pendingReqIdDigistSecret))
- throw new EAAFConfigurationException("config.08", new Object[] {CONFIG_PROP_PENDINGREQUESTID_DIGIST_SECRET});
-
- digistAlgorithm = baseConfig.getBasicConfiguration(CONFIG_PROP_PENDINGREQUESTID_DIGIST_ALGORITHM, DEFAULT_PENDINGREQUESTID_DIGIST_ALGORITHM);
-
- maxPendingRequestIdLifeTime = Integer.valueOf(
- baseConfig.getBasicConfiguration(CONFIG_PROP_PENDINGREQUESTID_MAX_LIFETIME, DEFAULT_PENDINGREQUESTID_MAX_LIFETIME));
-
- try {
- final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WITHHMACSHA256");
- final KeySpec spec = new PBEKeySpec(pendingReqIdDigistSecret.toCharArray(), salt, 10000, 128);
- key = keyFactory.generateSecret(spec);
-
-
- } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
- log.error("Can NOT initialize TokenService with configuration object", e);
- throw new EAAFConfigurationException("config.09",
- new Object[] { CONFIG_PROP_PENDINGREQUESTID_DIGIST_SECRET,
- "Can NOT generate HMAC key"},
- e);
-
- }
-
- log.info(this.getClass().getName() + " initialized with digistAlg: {} and maxLifeTime: {}", digistAlgorithm, maxPendingRequestIdLifeTime);
-
- }
-
- private String buildInternalToken(String internalPendingReqId, DateTime now) {
- return new StringBuilder()
- .append(TOKEN_TEXTUAL_DATE_FORMAT.print(now))
- .append(TOKEN_SEPARATOR)
- .append(internalPendingReqId).toString();
- }
-
- private byte[] calculateHMAC(String toSign) throws EAAFIllegalStateException {
- try {
- final Mac mac = Mac.getInstance(digistAlgorithm);
- mac.init(key);
- return mac.doFinal(toSign.getBytes("UTF-8"));
-
- } catch (UnsupportedEncodingException | NoSuchAlgorithmException | InvalidKeyException e) {
- log.error("Can NOT generate secure pendingRequestId", e);
- throw new EAAFIllegalStateException(new Object[] {"Can NOT caluclate digist for secure pendingRequestId"}, e);
-
- }
-
- }
+public class SecurePendingRequestIdGenerationStrategy
+ implements IPendingRequestIdGenerationStrategy {
+ private static final Logger log =
+ LoggerFactory.getLogger(SecurePendingRequestIdGenerationStrategy.class);
+
+ @Autowired(required = true)
+ IConfiguration baseConfig;
+
+ public static final String CONFIG_PROP_PENDINGREQUESTID_DIGIST_SECRET =
+ "core.pendingrequestid.digist.secret";
+ public static final String CONFIG_PROP_PENDINGREQUESTID_DIGIST_ALGORITHM =
+ "core.pendingrequestid.digist.algorithm";
+ public static final String CONFIG_PROP_PENDINGREQUESTID_MAX_LIFETIME =
+ "core.pendingrequestid.maxlifetime";
+
+ public static final String DEFAULT_PENDINGREQUESTID_DIGIST_ALGORITHM = "HmacSHA256";
+ public static final String DEFAULT_PENDINGREQUESTID_MAX_LIFETIME = "300";
+
+ private static final int ENCODED_TOKEN_PARTS = 3;
+ private static final String TOKEN_SEPARATOR = "|";
+ private static final DateTimeFormatter TOKEN_TEXTUAL_DATE_FORMAT =
+ DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss SSS");
+
+ private int maxPendingRequestIdLifeTime = 300;
+ private final int maxPendingReqIdSize = 1024;
+ private String digistAlgorithm = null;
+ private SecretKey key = null;
+ private final byte[] salt = "notRequiredInThisScenario".getBytes(Charset.defaultCharset());
+
+ @Override
+ public String generateExternalPendingRequestId() throws EaafException {
+ try {
+ final String toSign = buildInternalToken(Random.nextLongRandom(), DateTime.now());
+ final StringBuilder externalPendingRequestId = new StringBuilder();
+ externalPendingRequestId.append(toSign);
+ externalPendingRequestId.append(TOKEN_SEPARATOR);
+ externalPendingRequestId.append(Base64.getEncoder().encodeToString(calculateHmac(toSign)));
+ return Base64.getUrlEncoder()
+ .encodeToString(externalPendingRequestId.toString().getBytes("UTF-8"));
+
+ } catch (final UnsupportedEncodingException e) {
+ throw new EaafException("internal.99", new Object[] {e.getMessage()}, e);
+
+ }
+
+ }
+
+ @Override
+ public String getPendingRequestIdWithOutChecks(final String externalPendingReqId)
+ throws PendingReqIdValidationException {
+ try {
+ final String[] tokenElements = extractTokens(externalPendingReqId);
+ return tokenElements[1];
+
+ } catch (final UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+
+ }
+ }
+
+ @Override
+ public String validateAndGetPendingRequestId(final String externalPendingReqId)
+ throws PendingReqIdValidationException {
+ try {
+ final String[] tokenElements = extractTokens(externalPendingReqId);
+ final String internalPendingReqId = tokenElements[1];
+ final DateTime timeStamp = TOKEN_TEXTUAL_DATE_FORMAT.parseDateTime(tokenElements[0]);
+
+ log.trace("Checking HMAC from externalPendingReqId ... ");
+ final byte[] tokenDigest = Base64.getDecoder().decode(tokenElements[2]);
+ final byte[] refDigist = calculateHmac(buildInternalToken(internalPendingReqId, timeStamp));
+ if (!Arrays.equals(tokenDigest, refDigist)) {
+ log.warn("Digest of Token does NOT match");
+ log.debug("Token: {} | Ref: {}", tokenDigest, refDigist);
+ throw new PendingReqIdValidationException(null,
+ "Digest of pendingRequestId does NOT match");
+
+ }
+ log.debug("PendingRequestId HMAC digest check successful");
+
+ log.trace("Checking valid period ... ");
+ final DateTime now = DateTime.now();
+ if (timeStamp.withFieldAdded(DurationFieldType.seconds(), maxPendingRequestIdLifeTime)
+ .isBefore(now)) {
+ log.warn("Token exceeds the valid period");
+ log.debug("Token: {} | Now: {}", timeStamp, now);
+ throw new PendingReqIdValidationException(internalPendingReqId,
+ "PendingRequestId exceeds the valid period");
+
+ }
+ log.debug("Token valid-period check successful");
+
+ return internalPendingReqId;
+
+
+ } catch (final IllegalArgumentException | EaafIllegalStateException e) {
+ log.warn("Token is NOT a valid String. Msg: {}", e.getMessage());
+ log.debug("TokenValue: {}", externalPendingReqId);
+ throw new PendingReqIdValidationException(null, "PendingReqId is NOT a valid String", e);
+
+ } catch (final UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+
+ }
+ }
+
+ @NonNull
+ private String[] extractTokens(@Nullable final String externalPendingReqId)
+ throws PendingReqIdValidationException, UnsupportedEncodingException {
+ if (StringUtils.isEmpty(externalPendingReqId)) {
+ log.info("PendingReqId is 'null' or empty");
+ throw new PendingReqIdValidationException(null, "PendingReqId is 'null' or empty");
+
+ }
+
+ log.trace("RAW external pendingReqId: {}", externalPendingReqId);
+ final byte[] externalPendingReqIdBytes = Base64.getUrlDecoder().decode(externalPendingReqId);
+
+ if (externalPendingReqIdBytes.length > maxPendingReqIdSize) {
+ log.warn("pendingReqId size exceeds {}", maxPendingReqIdSize);
+ throw new PendingReqIdValidationException(null,
+ "pendingReqId exceeds max.size: " + maxPendingReqIdSize);
+
+ }
+
+ final String stringToken = new String(externalPendingReqIdBytes, "UTF-8");
+ if (StringUtils.countMatches(stringToken, TOKEN_SEPARATOR) == ENCODED_TOKEN_PARTS - 1) {
+ final String[] tokenElements =
+ StringUtils.split(stringToken, TOKEN_SEPARATOR, ENCODED_TOKEN_PARTS);
+ return tokenElements;
+
+ } else {
+ log.warn("PendingRequestId has an unvalid format");
+ log.debug("PendingRequestId: {}", stringToken);
+ throw new PendingReqIdValidationException(null, "PendingReqId has an unvalid format");
+
+ }
+
+ }
+
+
+ @PostConstruct
+ private void initialize() throws EaafConfigurationException {
+ log.debug("Initializing " + this.getClass().getName() + " ... ");
+
+ final String pendingReqIdDigistSecret =
+ baseConfig.getBasicConfiguration(CONFIG_PROP_PENDINGREQUESTID_DIGIST_SECRET);
+ if (StringUtils.isEmpty(pendingReqIdDigistSecret)) {
+ throw new EaafConfigurationException("config.08",
+ new Object[] {CONFIG_PROP_PENDINGREQUESTID_DIGIST_SECRET});
+ }
+
+ digistAlgorithm = baseConfig.getBasicConfiguration(
+ CONFIG_PROP_PENDINGREQUESTID_DIGIST_ALGORITHM, DEFAULT_PENDINGREQUESTID_DIGIST_ALGORITHM);
+
+ maxPendingRequestIdLifeTime =
+ Integer.parseInt(baseConfig.getBasicConfiguration(CONFIG_PROP_PENDINGREQUESTID_MAX_LIFETIME,
+ DEFAULT_PENDINGREQUESTID_MAX_LIFETIME));
+
+ try {
+ final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WITHHMACSHA256");
+ final KeySpec spec = new PBEKeySpec(pendingReqIdDigistSecret.toCharArray(), salt, 10000, 128);
+ key = keyFactory.generateSecret(spec);
+
+
+ } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
+ log.error("Can NOT initialize TokenService with configuration object", e);
+ throw new EaafConfigurationException("config.09",
+ new Object[] {CONFIG_PROP_PENDINGREQUESTID_DIGIST_SECRET, "Can NOT generate HMAC key"},
+ e);
+
+ }
+
+ log.info(this.getClass().getName() + " initialized with digistAlg: {} and maxLifeTime: {}",
+ digistAlgorithm, maxPendingRequestIdLifeTime);
+
+ }
+
+ private String buildInternalToken(final String internalPendingReqId, final DateTime now) {
+ return new StringBuilder().append(TOKEN_TEXTUAL_DATE_FORMAT.print(now)).append(TOKEN_SEPARATOR)
+ .append(internalPendingReqId).toString();
+ }
+
+ private byte[] calculateHmac(final String toSign) throws EaafIllegalStateException {
+ try {
+ final Mac mac = Mac.getInstance(digistAlgorithm);
+ mac.init(key);
+ return mac.doFinal(toSign.getBytes("UTF-8"));
+
+ } catch (UnsupportedEncodingException | NoSuchAlgorithmException | InvalidKeyException e) {
+ log.error("Can NOT generate secure pendingRequestId", e);
+ throw new EaafIllegalStateException(
+ new Object[] {"Can NOT caluclate digist for secure pendingRequestId"}, e);
+
+ }
+
+ }
}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/ServletUtils.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/ServletUtils.java
index 38e873e2..0d16e9cd 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/ServletUtils.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/ServletUtils.java
@@ -1,43 +1,41 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+ */
package at.gv.egiz.eaaf.core.impl.utils;
import javax.servlet.http.HttpServletRequest;
public class ServletUtils {
-
-
- public static String getBaseUrl( HttpServletRequest request ) {
- if ( ( request.getServerPort() == 80 ) ||
- ( request.getServerPort() == 443 ) )
- return request.getScheme() + "://" +
- request.getServerName() +
- request.getContextPath();
- else
- return request.getScheme() + "://" +
- request.getServerName() + ":" + request.getServerPort() +
- request.getContextPath();
- }
-
+
+ /**
+ * Get Context URL from http request.
+ *
+ * @param request http Request
+ * @return Context URL
+ */
+ public static String getBaseUrl(final HttpServletRequest request) {
+ if ((request.getServerPort() == 80) || (request.getServerPort() == 443)) {
+ return request.getScheme() + "://" + request.getServerName() + request.getContextPath();
+ } else {
+ return request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
+ + request.getContextPath();
+ }
+ }
+
}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SimplePendingRequestIdGenerationStrategy.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SimplePendingRequestIdGenerationStrategy.java
index 6b8fe9b7..049f7175 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SimplePendingRequestIdGenerationStrategy.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SimplePendingRequestIdGenerationStrategy.java
@@ -1,38 +1,42 @@
package at.gv.egiz.eaaf.core.impl.utils;
-import org.apache.commons.lang3.StringUtils;
-
import at.gv.egiz.eaaf.core.api.utils.IPendingRequestIdGenerationStrategy;
import at.gv.egiz.eaaf.core.exceptions.PendingReqIdValidationException;
+import org.apache.commons.lang3.StringUtils;
/**
- * Simple pendingRequestId generation strategy that facilitates no extended validation
- *
+ * Simple pendingRequestId generation strategy that facilitates no extended validation.
+ *
* @author tlenz
*
*/
-public class SimplePendingRequestIdGenerationStrategy implements IPendingRequestIdGenerationStrategy {
-
- @Override
- public String generateExternalPendingRequestId() {
- return Random.nextLongRandom();
-
- }
-
- @Override
- public String validateAndGetPendingRequestId(String pendingReqId) throws PendingReqIdValidationException {
- return getPendingRequestIdWithOutChecks(pendingReqId);
-
- }
-
- @Override
- public String getPendingRequestIdWithOutChecks(String externalPendingReqId) throws PendingReqIdValidationException {
- if (StringUtils.isEmpty(externalPendingReqId))
- throw new PendingReqIdValidationException(externalPendingReqId, "PendingRequestId is empty or null");
-
-
-
- return externalPendingReqId;
- }
+public class SimplePendingRequestIdGenerationStrategy
+ implements IPendingRequestIdGenerationStrategy {
+
+ @Override
+ public String generateExternalPendingRequestId() {
+ return Random.nextLongRandom();
+
+ }
+
+ @Override
+ public String validateAndGetPendingRequestId(final String pendingReqId)
+ throws PendingReqIdValidationException {
+ return getPendingRequestIdWithOutChecks(pendingReqId);
+
+ }
+
+ @Override
+ public String getPendingRequestIdWithOutChecks(final String externalPendingReqId)
+ throws PendingReqIdValidationException {
+ if (StringUtils.isEmpty(externalPendingReqId)) {
+ throw new PendingReqIdValidationException(externalPendingReqId,
+ "PendingRequestId is empty or null");
+ }
+
+
+
+ return externalPendingReqId;
+ }
}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/StreamUtils.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/StreamUtils.java
index 530da777..cc784870 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/StreamUtils.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/StreamUtils.java
@@ -1,29 +1,22 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
package at.gv.egiz.eaaf.core.impl.utils;
@@ -32,38 +25,37 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.io.PrintStream;
/**
* Utility methods for streams.
- *
+ *
* @author Patrick Peck
* @version $Id$
*/
public class StreamUtils {
-
+
/**
* Compare the contents of two <code>InputStream</code>s.
- *
+ *
* @param is1 The 1st <code>InputStream</code> to compare.
* @param is2 The 2nd <code>InputStream</code> to compare.
- * @return boolean <code>true</code>, if both streams contain the exactly the
- * same content, <code>false</code> otherwise.
+ * @return boolean <code>true</code>, if both streams contain the exactly the same content,
+ * <code>false</code> otherwise.
* @throws IOException An error occurred reading one of the streams.
*/
- public static boolean compareStreams(InputStream is1, InputStream is2)
- throws IOException {
-
- byte[] buf1 = new byte[256];
- byte[] buf2 = new byte[256];
+ public static boolean compareStreams(final InputStream is1, final InputStream is2)
+ throws IOException {
+
+ final byte[] buf1 = new byte[256];
+ final byte[] buf2 = new byte[256];
int length1;
int length2;
-
+
try {
while (true) {
length1 = is1.read(buf1);
length2 = is2.read(buf2);
-
+
if (length1 != length2) {
return false;
}
@@ -74,128 +66,125 @@ public class StreamUtils {
return false;
}
}
- } catch (IOException e) {
+ } catch (final IOException e) {
throw e;
} finally {
// close both streams
try {
is1.close();
is2.close();
- } catch (IOException e) {
- // ignore this
+ } catch (final IOException e) {
+ e.printStackTrace();
+
}
}
}
-
+
/**
* Compare two byte arrays, up to a given maximum length.
- *
+ *
* @param b1 1st byte array to compare.
* @param b2 2nd byte array to compare.
* @param length The maximum number of bytes to compare.
- * @return <code>true</code>, if the byte arrays are equal, <code>false</code>
- * otherwise.
+ * @return <code>true</code>, if the byte arrays are equal, <code>false</code> otherwise.
*/
- private static boolean compareBytes(byte[] b1, byte[] b2, int length) {
+ private static boolean compareBytes(final byte[] b1, final byte[] b2, final int length) {
if (b1.length != b2.length) {
return false;
}
-
+
for (int i = 0; i < b1.length && i < length; i++) {
if (b1[i] != b2[i]) {
return false;
}
}
-
+
return true;
}
/**
* Reads a byte array from a stream.
+ *
* @param in The <code>InputStream</code> to read.
* @return The bytes contained in the given <code>InputStream</code>.
* @throws IOException on any exception thrown
*/
- public static byte[] readStream(InputStream in) throws IOException {
+ public static byte[] readStream(final InputStream in) throws IOException {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
+ final ByteArrayOutputStream out = new ByteArrayOutputStream();
copyStream(in, out, null);
-
- /*
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- int b;
- while ((b = in.read()) >= 0)
- out.write(b);
-
- */
+
+ /*
+ * ByteArrayOutputStream out = new ByteArrayOutputStream(); int b; while ((b = in.read()) >= 0)
+ * out.write(b);
+ *
+ */
in.close();
return out.toByteArray();
}
/**
* Reads a <code>String</code> from a stream, using given encoding.
+ *
* @param in The <code>InputStream</code> to read.
- * @param encoding The character encoding to use for converting the bytes
- * of the <code>InputStream</code> into a <code>String</code>.
- * @return The content of the given <code>InputStream</code> converted into
- * a <code>String</code>.
+ * @param encoding The character encoding to use for converting the bytes of the
+ * <code>InputStream</code> into a <code>String</code>.
+ * @return The content of the given <code>InputStream</code> converted into a <code>String</code>.
* @throws IOException on any exception thrown
*/
- public static String readStream(InputStream in, String encoding) throws IOException {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
+ public static String readStream(final InputStream in, final String encoding) throws IOException {
+ final ByteArrayOutputStream out = new ByteArrayOutputStream();
copyStream(in, out, null);
/*
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- int b;
- while ((b = in.read()) >= 0)
- out.write(b);
- */
+ * ByteArrayOutputStream out = new ByteArrayOutputStream(); int b; while ((b = in.read()) >= 0)
+ * out.write(b);
+ */
in.close();
return out.toString(encoding);
}
-
+
/**
- * Reads all data (until EOF is reached) from the given source to the
- * destination stream. If the destination stream is null, all data is dropped.
- * It uses the given buffer to read data and forward it. If the buffer is
- * null, this method allocates a buffer.
+ * Reads all data (until EOF is reached) from the given source to the destination stream. If the
+ * destination stream is null, all data is dropped. It uses the given buffer to read data and
+ * forward it. If the buffer is null, this method allocates a buffer.
*
* @param source The stream providing the data.
- * @param destination The stream that takes the data. If this is null, all
- * data from source will be read and discarded.
- * @param buffer The buffer to use for forwarding. If it is null, the method
- * allocates a buffer.
- * @exception IOException If reading from the source or writing to the
- * destination fails.
+ * @param destination The stream that takes the data. If this is null, all data from source will
+ * be read and discarded.
+ * @param buffer The buffer to use for forwarding. If it is null, the method allocates a buffer.
+ * @exception IOException If reading from the source or writing to the destination fails.
*/
- private static void copyStream(InputStream source, OutputStream destination, byte[] buffer) throws IOException {
+ private static void copyStream(final InputStream source, final OutputStream destination,
+ byte[] buffer) throws IOException {
if (source == null) {
throw new NullPointerException("Argument \"source\" must not be null.");
}
if (buffer == null) {
buffer = new byte[8192];
}
-
+
if (destination != null) {
int bytesRead;
while ((bytesRead = source.read(buffer)) >= 0) {
destination.write(buffer, 0, bytesRead);
}
} else {
- while (source.read(buffer) >= 0);
- }
- }
-
- /**
- * Gets the stack trace of the <code>Throwable</code> passed in as a string.
- * @param t The <code>Throwable</code>.
- * @return a String representing the stack trace of the <code>Throwable</code>.
- */
- public static String getStackTraceAsString(Throwable t)
- {
- ByteArrayOutputStream stackTraceBIS = new ByteArrayOutputStream();
- t.printStackTrace(new PrintStream(stackTraceBIS));
- return new String(stackTraceBIS.toByteArray());
+ while (source.read(buffer) >= 0) {
+
+ }
+ }
}
+
+ // /**
+ // * Gets the stack trace of the <code>Throwable</code> passed in as a string.
+ // *
+ // * @param t The <code>Throwable</code>.
+ // * @return a String representing the stack trace of the <code>Throwable</code>.
+ // */
+ // public static String getStackTraceAsString(final Throwable t) {
+ // final ByteArrayOutputStream stackTraceBis = new ByteArrayOutputStream();
+ // t.printStackTrace(new PrintStream(stackTraceBis));
+ // return new String(stackTraceBis.toByteArray());
+ // }
}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/TransactionIDUtils.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/TransactionIDUtils.java
deleted file mode 100644
index 2e016848..00000000
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/TransactionIDUtils.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
- *
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- * https://joinup.ec.europa.eu/news/understanding-eupl-v12
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-package at.gv.egiz.eaaf.core.impl.utils;
-
-
-import at.gv.egiz.eaaf.core.api.IRequest;
-
-/**
- * @author tlenz
- *
- */
-public class TransactionIDUtils {
-
- //MDC variables for logging
- public static final String MDC_TRANSACTION_ID = "transactionId";
- public static final String MDC_SESSION_ID = "sessionId";
- public static final String MDC_SERVICEPROVIDER_ID = "oaId";
-
- /**
- * Set all MDC variables from pending request to this threat context<br>
- * These includes SessionID, TransactionID, and unique service-provider identifier
- *
- * @param pendingRequest
- */
- public static void setAllLoggingVariables(IRequest pendingRequest) {
- setTransactionId(pendingRequest.getUniqueTransactionIdentifier());
- setSessionId(pendingRequest.getUniqueSessionIdentifier());
- setServiceProviderId(pendingRequest.getServiceProviderConfiguration().getUniqueIdentifier());
-
- }
-
- /**
- * Remove all MDC variables from this threat context
- *
- */
- public static void removeAllLoggingVariables() {
- removeSessionId();
- removeTransactionId();
- removeServiceProviderId();
-
- }
-
-
- public static void setServiceProviderId(String oaUniqueId) {
- org.slf4j.MDC.put(MDC_SERVICEPROVIDER_ID, oaUniqueId);
-
- }
-
- public static void removeServiceProviderId() {
- org.slf4j.MDC.remove(MDC_SERVICEPROVIDER_ID);
-
- }
-
- public static void setTransactionId(String pendingRequestID) {
- org.slf4j.MDC.put(MDC_TRANSACTION_ID,
- "TID-" + pendingRequestID);
-
- }
-
- public static void removeTransactionId() {
- org.slf4j.MDC.remove(MDC_TRANSACTION_ID);
-
- }
-
- public static void setSessionId(String uniqueSessionId) {
- org.slf4j.MDC.put(MDC_SESSION_ID,
- "SID-" + uniqueSessionId);
-
- }
-
- public static void removeSessionId() {
- org.slf4j.MDC.remove(MDC_SESSION_ID);
-
- }
-
-
-}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/TransactionIdUtils.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/TransactionIdUtils.java
new file mode 100644
index 00000000..3875e587
--- /dev/null
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/TransactionIdUtils.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.gv.egiz.eaaf.core.impl.utils;
+
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+
+/**
+ * Transaction Identifier Utils.
+ *
+ * @author tlenz
+ *
+ */
+public class TransactionIdUtils {
+
+ // MDC variables for logging
+ public static final String MDC_TRANSACTION_ID = "transactionId";
+ public static final String MDC_SESSION_ID = "sessionId";
+ public static final String MDC_SERVICEPROVIDER_ID = "oaId";
+
+ /**
+ * Set all MDC variables from pending request to this threat context.<br>
+ * These includes SessionID, TransactionID, and unique service-provider identifier
+ *
+ * @param pendingRequest Http request object
+ */
+ public static void setAllLoggingVariables(final IRequest pendingRequest) {
+ setTransactionId(pendingRequest.getUniqueTransactionIdentifier());
+ setSessionId(pendingRequest.getUniqueSessionIdentifier());
+ setServiceProviderId(pendingRequest.getServiceProviderConfiguration().getUniqueIdentifier());
+
+ }
+
+ /**
+ * Remove all MDC variables from this threat context.
+ *
+ */
+ public static void removeAllLoggingVariables() {
+ removeSessionId();
+ removeTransactionId();
+ removeServiceProviderId();
+
+ }
+
+
+ public static void setServiceProviderId(final String oaUniqueId) {
+ org.slf4j.MDC.put(MDC_SERVICEPROVIDER_ID, oaUniqueId);
+
+ }
+
+ public static void removeServiceProviderId() {
+ org.slf4j.MDC.remove(MDC_SERVICEPROVIDER_ID);
+
+ }
+
+ public static void setTransactionId(final String pendingRequestID) {
+ org.slf4j.MDC.put(MDC_TRANSACTION_ID, "TID-" + pendingRequestID);
+
+ }
+
+ public static void removeTransactionId() {
+ org.slf4j.MDC.remove(MDC_TRANSACTION_ID);
+
+ }
+
+ public static void setSessionId(final String uniqueSessionId) {
+ org.slf4j.MDC.put(MDC_SESSION_ID, "SID-" + uniqueSessionId);
+
+ }
+
+ public static void removeSessionId() {
+ org.slf4j.MDC.remove(MDC_SESSION_ID);
+
+ }
+
+
+}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/X509Utils.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/X509Utils.java
index b3fb42c4..00a31a13 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/X509Utils.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/X509Utils.java
@@ -7,56 +7,45 @@ import javax.security.auth.x500.X500Principal;
public class X509Utils {
- /**
- * Sorts the Certificate Chain by IssuerDN and SubjectDN. The [0]-Element should be the Hostname,
- * the last Element should be the Root Certificate.
- *
- * @param certs
- * The first element must be the correct one.
- * @return sorted Certificate Chain
- */
- public static List<X509Certificate> sortCertificates(
- List<X509Certificate> certs)
- {
- int length = certs.size();
- if (certs.size() <= 1)
- {
- return certs;
- }
+ /**
+ * Sorts the Certificate Chain by IssuerDN and SubjectDN. The [0]-Element should be the Hostname,
+ * the last Element should be the Root Certificate.
+ *
+ * @param certs The first element must be the correct one.
+ * @return sorted Certificate Chain
+ */
+ public static List<X509Certificate> sortCertificates(final List<X509Certificate> certs) {
+ final int length = certs.size();
+ if (certs.size() <= 1) {
+ return certs;
+ }
- for (X509Certificate cert : certs)
- {
- if (cert == null)
- {
- throw new NullPointerException();
- }
- }
+ for (final X509Certificate cert : certs) {
+ if (cert == null) {
+ throw new NullPointerException();
+ }
+ }
- for (int i = 0; i < length; i++)
- {
- boolean found = false;
- X500Principal issuer = certs.get(i).getIssuerX500Principal();
- for (int j = i + 1; j < length; j++)
- {
- X500Principal subject = certs.get(j).getSubjectX500Principal();
- if (issuer.equals(subject))
- {
- // sorting necessary?
- if (i + 1 != j)
- {
- X509Certificate tmp = certs.get(i + 1);
- certs.set(i + 1, certs.get(j));
- certs.set(j, tmp);
- }
- found = true;
- }
- }
- if (!found)
- {
- break;
- }
- }
+ for (int i = 0; i < length; i++) {
+ boolean found = false;
+ final X500Principal issuer = certs.get(i).getIssuerX500Principal();
+ for (int j = i + 1; j < length; j++) {
+ final X500Principal subject = certs.get(j).getSubjectX500Principal();
+ if (issuer.equals(subject)) {
+ // sorting necessary?
+ if (i + 1 != j) {
+ final X509Certificate tmp = certs.get(i + 1);
+ certs.set(i + 1, certs.get(j));
+ certs.set(j, tmp);
+ }
+ found = true;
+ }
+ }
+ if (!found) {
+ break;
+ }
+ }
- return certs;
- }
+ return certs;
+ }
}
diff --git a/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/impl/logging/JUnitTestStatusMessenger.java b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/impl/logging/JUnitTestStatusMessenger.java
index 5cdd404c..be5d95b1 100644
--- a/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/impl/logging/JUnitTestStatusMessenger.java
+++ b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/impl/logging/JUnitTestStatusMessenger.java
@@ -3,54 +3,59 @@ package at.gv.egiz.eaaf.core.impl.logging;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
-
import at.gv.egiz.eaaf.core.api.IStatusMessenger;
public class JUnitTestStatusMessenger implements IStatusMessenger {
- private final Map<String, String> msgStore = new HashMap<>();
-
- @Override
- public String getMessage(String messageId, Object[] parameters) {
- final String msg = getMessageWithoutDefault(messageId, parameters);
- if (msg != null) {
- return msg;
-
- } else {
- return MessageFormat.format(messageId, parameters);
-
- }
-
- }
-
- @Override
- public String getMessageWithoutDefault(String messageId, Object[] parameters) {
- if (messageId != null) {
- if (msgStore.containsKey(messageId)) {
- return MessageFormat.format(msgStore.get(messageId), parameters);
-
- }
- }
-
- return null;
- }
-
- @Override
- public String getResponseErrorCode(Throwable throwable) {
- return null;
- }
-
- @Override
- public String mapInternalErrorToExternalError(String intErrorCode) {
- return null;
- }
-
- public void addMsg(String msgCode, String msg) {
- if (!msgStore.containsKey(msgCode)) {
- msgStore.put(msgCode, msg);
-
- }
-
- }
-
+ private final Map<String, String> msgStore = new HashMap<>();
+
+ @Override
+ public String getMessage(final String messageId, final Object[] parameters) {
+ final String msg = getMessageWithoutDefault(messageId, parameters);
+ if (msg != null) {
+ return msg;
+
+ } else {
+ return MessageFormat.format(messageId, parameters);
+
+ }
+
+ }
+
+ @Override
+ public String getMessageWithoutDefault(final String messageId, final Object[] parameters) {
+ if (messageId != null) {
+ if (msgStore.containsKey(messageId)) {
+ return MessageFormat.format(msgStore.get(messageId), parameters);
+
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public String getResponseErrorCode(final Throwable throwable) {
+ return null;
+ }
+
+ @Override
+ public String mapInternalErrorToExternalError(final String intErrorCode) {
+ return null;
+ }
+
+ /**
+ * Add a message into Message-Store.
+ *
+ * @param msgCode message-code
+ * @param msg message
+ */
+ public void addMsg(final String msgCode, final String msg) {
+ if (!msgStore.containsKey(msgCode)) {
+ msgStore.put(msgCode, msg);
+
+ }
+
+ }
+
}
diff --git a/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/impl/utils/test/KeyValueUtilsTest.java b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/impl/utils/test/KeyValueUtilsTest.java
new file mode 100644
index 00000000..258c3210
--- /dev/null
+++ b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/impl/utils/test/KeyValueUtilsTest.java
@@ -0,0 +1,446 @@
+package at.gv.egiz.eaaf.core.impl.utils.test;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import com.google.common.collect.Sets;
+
+@RunWith(BlockJUnit4ClassRunner.class)
+public class KeyValueUtilsTest {
+
+ @Test
+ public void getFirstChildTest_1() {
+ final String prefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final String child = RandomStringUtils.randomAlphabetic(2);
+ final String key = prefix + KeyValueUtils.KEY_DELIMITER + child + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(4);
+ final String resut = KeyValueUtils.getFirstChildAfterPrefix(key, prefix);
+ Assert.assertEquals("First child not match", child, resut);
+
+ }
+
+ @Test
+ public void getFirstChildTest_2() {
+ final String prefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final String child = RandomStringUtils.randomAlphabetic(2);
+ final String key = prefix + KeyValueUtils.KEY_DELIMITER + child;
+ final String resut = KeyValueUtils.getFirstChildAfterPrefix(key, prefix);
+ Assert.assertEquals("First child not match", child, resut);
+
+ }
+
+ @Test
+ public void getFirstChildTest_3() {
+ final String prefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final String child = RandomStringUtils.randomAlphabetic(2);
+ final String key = prefix + KeyValueUtils.KEY_DELIMITER + child;
+ final String resut = KeyValueUtils.getFirstChildAfterPrefix(key, key);
+ Assert.assertNull("First child not null", resut);
+
+ }
+
+ @Test
+ public void getFirstChildTest_4() {
+ final String prefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final String child = RandomStringUtils.randomAlphabetic(2);
+ final String key = prefix + KeyValueUtils.KEY_DELIMITER + child;
+ final String resut = KeyValueUtils.getFirstChildAfterPrefix(
+ RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER + key, key);
+ Assert.assertNull("First child not null", resut);
+
+ }
+
+ @Test
+ public void getFirstChildTest_5() {
+ final String prefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final String child = RandomStringUtils.randomAlphabetic(2);
+ final String key = child + KeyValueUtils.KEY_DELIMITER + prefix;
+ final String resut = KeyValueUtils.getFirstChildAfterPrefix(key, null);
+ Assert.assertEquals("First child not match", child, resut);
+
+ }
+
+ @Test
+ public void getFirstChildTest_6() {
+ final String prefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final String child = RandomStringUtils.randomAlphabetic(2);
+ final String key = prefix + KeyValueUtils.KEY_DELIMITER + child;
+ final String resut = KeyValueUtils.getFirstChildAfterPrefix(key, key);
+ Assert.assertNull("First child not null", resut);
+
+ }
+
+ @Test
+ public void getPrefixFromKey_1() {
+ final String prefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final String child = RandomStringUtils.randomAlphabetic(2);
+ final String key = prefix + KeyValueUtils.KEY_DELIMITER + child;
+ final String resut = KeyValueUtils.getPrefixFromKey(key, child);
+ Assert.assertEquals("Prefix not match", prefix, resut);
+
+ }
+
+ @Test
+ public void getPrefixFromKey_2() {
+ final String child = RandomStringUtils.randomAlphabetic(2);
+ final String resut = KeyValueUtils.getPrefixFromKey(null, child);
+ Assert.assertNull("Prefix not null", resut);
+
+ }
+
+ @Test
+ public void getPrefixFromKey_3() {
+ final String prefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final String key = prefix + KeyValueUtils.KEY_DELIMITER + RandomStringUtils.randomAlphabetic(4);
+ final String resut = KeyValueUtils.getPrefixFromKey(key, RandomStringUtils.randomAlphabetic(5));
+ Assert.assertNull("Prefix not null", resut);
+
+ }
+
+ @Test
+ public void getPrefixFromKey_4() {
+ final String prefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final String child = KeyValueUtils.KEY_DELIMITER + RandomStringUtils.randomAlphabetic(2);
+ final String key = prefix + child;
+ final String resut = KeyValueUtils.getPrefixFromKey(key, child);
+ Assert.assertEquals("Prefix not match", prefix, resut);
+
+ }
+
+ @Test
+ public void getPrefixFromKey_5() {
+ final String key = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final String resut = KeyValueUtils.getPrefixFromKey(key, null);
+ Assert.assertNull("Prefix not null", resut);
+
+ }
+
+ @Test
+ public void getRemovePrefixesFromKeys_1() {
+ final String testPrefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final Map<String, String> testMap = generateTestMap(testPrefix, 5, 5);
+
+ final Map<String, String> result = KeyValueUtils.removePrefixFromKeys(testMap, testPrefix);
+ Assert.assertNotNull("Result is null", result);
+ Assert.assertFalse("Result is empty", result.isEmpty());
+ Assert.assertEquals("Result size not match", 5, result.size());
+ final Iterator<Entry<String, String>> it = result.entrySet().iterator();
+ while (it.hasNext()) {
+ final Entry<String, String> next = it.next();
+ Assert.assertNotNull("Key is null", next.getKey());
+ Assert.assertNotNull("Value is null", next.getValue());
+ Assert.assertTrue("Key is null", testMap.containsKey(testPrefix + "." + next.getKey()));
+ Assert.assertEquals("Value not match", testMap.get(testPrefix + "." + next.getKey()),
+ next.getValue());
+
+ }
+
+ }
+
+ @Test
+ public void getSubSetWithPrefixTest_1() {
+ final String testPrefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final Map<String, String> testMap = generateTestMap(testPrefix, 5, 5);
+
+ final Map<String, String> result = KeyValueUtils.getSubSetWithPrefix(testMap, testPrefix);
+ Assert.assertNotNull("Result is null", result);
+ Assert.assertFalse("Result is empty", result.isEmpty());
+ Assert.assertEquals("Result size not match", 5, result.size());
+ final Iterator<Entry<String, String>> it = result.entrySet().iterator();
+ while (it.hasNext()) {
+ final Entry<String, String> next = it.next();
+ Assert.assertNotNull("Key is null", next.getKey());
+ Assert.assertNotNull("Value is null", next.getValue());
+ Assert.assertTrue("Key is null", testMap.containsKey(testPrefix + "." + next.getKey()));
+ Assert.assertEquals("Value not match", testMap.get(testPrefix + "." + next.getKey()),
+ next.getValue());
+
+ }
+
+ }
+
+ @Test
+ public void makeKeysAbsolutTest_1() {
+ final String absTestPrefixtestPrefix = RandomStringUtils.randomAlphabetic(4)
+ + KeyValueUtils.KEY_DELIMITER + RandomStringUtils.randomAlphabetic(6)
+ + KeyValueUtils.KEY_DELIMITER + RandomStringUtils.randomAlphabetic(5);
+ final String prefix = absTestPrefixtestPrefix + "." + RandomStringUtils.randomAlphabetic(4);
+ final Map<String, String> testMap = generateTestMap(prefix, 5, 5);
+ final Map<String, String> result =
+ KeyValueUtils.makeKeysAbsolut(testMap, absTestPrefixtestPrefix, prefix);
+
+ Assert.assertNotNull("Result is null", result);
+ Assert.assertFalse("Result is empty", result.isEmpty());
+ Assert.assertEquals("Result size not match", 10, result.size());
+ final Iterator<Entry<String, String>> it = result.entrySet().iterator();
+ while (it.hasNext()) {
+ final Entry<String, String> next = it.next();
+ Assert.assertNotNull("Key is null", next.getKey());
+ Assert.assertNotNull("Value is null", next.getValue());
+ if (testMap.containsKey(next.getKey())) {
+ Assert.assertEquals("Value not match", testMap.get(next.getKey()), next.getValue());
+ } else {
+ Assert.assertTrue("Key not found",
+ testMap.containsKey(next.getKey().substring(absTestPrefixtestPrefix.length() + 1)));
+ Assert.assertEquals("Value not match",
+ testMap.get(next.getKey().substring(absTestPrefixtestPrefix.length() + 1)),
+ next.getValue());
+ }
+ }
+ }
+
+ @Test
+ public void getParentKeyTest_1() {
+ final String testPrefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final String result =
+ KeyValueUtils.getParentKey(testPrefix + "." + RandomStringUtils.randomAlphabetic(5));
+ Assert.assertNotNull("Result is null", result);
+ Assert.assertEquals("Parent not match", testPrefix, result);
+
+ }
+
+ @Test
+ public void getParentKeyTest_2() {
+ final String result = KeyValueUtils.getParentKey(RandomStringUtils.randomAlphabetic(5));
+ Assert.assertNotNull("Result is null", result);
+ Assert.assertTrue("Result not empty", result.isEmpty());
+
+ }
+
+ @Test
+ public void findNextFreeListCoutnerTest_1() {
+ final String testPrefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final java.util.List<String> propList = new ArrayList<>();
+ propList.add(testPrefix + ".1");
+ propList.add(testPrefix + ".2");
+ propList.add(testPrefix + ".0");
+ propList.add(testPrefix + ".4");
+ propList.add(testPrefix + ".3");
+
+ final int result = KeyValueUtils.findNextFreeListCounter(Sets.newHashSet(propList), testPrefix);
+ Assert.assertEquals("Next free element not fount", 5, result);
+
+ }
+
+ @Test
+ public void findNextFreeListCoutnerTest_2() {
+ final String testPrefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final java.util.List<String> propList = new ArrayList<>();
+ propList.add(testPrefix + ".1");
+ propList.add(testPrefix + ".5");
+ propList.add(testPrefix + ".0");
+ propList.add(testPrefix + ".4");
+ propList.add(testPrefix + ".3");
+
+ final int result = KeyValueUtils.findNextFreeListCounter(Sets.newHashSet(propList), testPrefix);
+ Assert.assertEquals("Next free element not fount", 6, result);
+
+ }
+
+ @Test
+ public void findNextFreeListCoutnerTest_3() {
+ final String testPrefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final java.util.List<String> propList = new ArrayList<>();
+
+ final int result = KeyValueUtils.findNextFreeListCounter(Sets.newHashSet(propList), testPrefix);
+ Assert.assertEquals("Next free element not fount", 0, result);
+
+ }
+
+ @Test
+ public void findNextFreeListCoutnerTest_4() {
+ final String testPrefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final java.util.List<String> propList = new ArrayList<>();
+
+ final int result =
+ KeyValueUtils.findNextFreeListCounter(propList.stream().toArray(String[]::new), testPrefix);
+ Assert.assertEquals("Next free element not fount", 0, result);
+
+ }
+
+ @Test
+ public void normalizeCsvValueStringTest_1() {
+ final String csv1 = RandomStringUtils.randomAlphanumeric(5);
+ final String csv2 = RandomStringUtils.randomAlphanumeric(5);
+ final String csv3 = RandomStringUtils.randomAlphanumeric(5);
+ final String csv4 = RandomStringUtils.randomAlphanumeric(5);
+ final String testValue = " " + csv1 + " ," + csv2 + "," + csv3 + "\n," + csv4 + " ";
+
+ final String result = KeyValueUtils.normalizeCsvValueString(testValue);
+
+ Assert.assertNotNull("Result is null", result);
+ Assert.assertFalse("Result is empty", result.isEmpty());
+ final String[] check = result.split(",");
+ Assert.assertEquals("Result size wrong", 4, check.length);
+ Assert.assertEquals("Result 1 wrong", csv1, check[0]);
+ Assert.assertEquals("Result 2 wrong", csv2, check[1]);
+ Assert.assertEquals("Result 3 wrong", csv3, check[2]);
+ Assert.assertEquals("Result 4 wrong", csv4, check[3]);
+
+ }
+
+ @Test
+ public void isCsvValueStringTest_1() {
+ final String csv1 = RandomStringUtils.randomAlphanumeric(5);
+ final String csv2 = RandomStringUtils.randomAlphanumeric(5);
+ final String csv3 = RandomStringUtils.randomAlphanumeric(5);
+ final String csv4 = RandomStringUtils.randomAlphanumeric(5);
+ final String testValue = " " + csv1 + " ," + csv2 + "," + csv3 + "\n," + csv4 + " ";
+ final boolean result = KeyValueUtils.isCsvValueString(testValue);
+ Assert.assertTrue("CSV value not detected", result);
+
+ }
+
+ @Test
+ public void isCsvValueStringTest_2() {
+ final String csv1 = RandomStringUtils.randomAlphanumeric(5);
+ final String testValue = " " + csv1 + " ,";
+ final boolean result = KeyValueUtils.isCsvValueString(testValue);
+ Assert.assertFalse("CSV value not detected", result);
+
+ }
+
+ @Test
+ public void isCsvValueStringTest_3() {
+ final String csv1 = RandomStringUtils.randomAlphanumeric(5);
+ final String testValue = " " + csv1;
+ final boolean result = KeyValueUtils.isCsvValueString(testValue);
+ Assert.assertFalse("CSV value not detected", result);
+
+ }
+
+ @Test
+ public void getListOfCsvValuesTest_1() {
+ final String csv1 = RandomStringUtils.randomAlphanumeric(5);
+ final String csv2 = RandomStringUtils.randomAlphanumeric(5);
+ final String csv3 = RandomStringUtils.randomAlphanumeric(5);
+ final String csv4 = RandomStringUtils.randomAlphanumeric(5);
+ final String testValue = " " + csv1 + " ," + csv2 + "," + csv3 + "\n," + csv4 + " ";
+
+ final List<String> result = KeyValueUtils.getListOfCsvValues(testValue);
+
+ Assert.assertNotNull("Result is null", result);
+ Assert.assertFalse("Result is empty", result.isEmpty());
+ Assert.assertEquals("Result size wrong", 4, result.size());
+ Assert.assertEquals("Result 1 wrong", csv1, result.get(0));
+ Assert.assertEquals("Result 2 wrong", csv2, result.get(1));
+ Assert.assertEquals("Result 3 wrong", csv3, result.get(2));
+ Assert.assertEquals("Result 4 wrong", csv4, result.get(3));
+
+ }
+
+ @Test
+ public void convertListToMapTest_1() {
+ final java.util.List<String> propList = new ArrayList<>();
+ final String prefix = RandomStringUtils.randomAlphabetic(4) + ".";
+ final String key1 = RandomStringUtils.randomAlphabetic(5);
+ final String value1 = RandomStringUtils.randomAlphanumeric(10);
+ final String key2 = RandomStringUtils.randomAlphabetic(5);
+ final String value2 = RandomStringUtils.randomAlphanumeric(10);
+ final String key3 = RandomStringUtils.randomAlphabetic(5);
+ final String value3 = RandomStringUtils.randomAlphanumeric(10);
+ final String key4 = RandomStringUtils.randomAlphabetic(5);
+ final String value4 = RandomStringUtils.randomAlphanumeric(10);
+ final String key5 = RandomStringUtils.randomAlphabetic(5);
+ final String value5 = RandomStringUtils.randomAlphanumeric(10);
+ final String key6 = RandomStringUtils.randomAlphabetic(5);
+ final String value6 = "=" + RandomStringUtils.randomAlphanumeric(10);
+
+ propList.add(prefix + key1 + "=" + value1);
+ propList.add(prefix + key2 + "=" + value2);
+ propList.add(prefix + key3 + "=" + value3);
+ propList.add(prefix + key4 + "=" + value4);
+ propList.add(prefix + key5 + "+" + value5);
+ propList.add(prefix + key6 + "=" + value6);
+
+ final Map<String, String> result = KeyValueUtils.convertListToMap(propList);
+ Assert.assertNotNull("Result is null", result);
+ Assert.assertFalse("Result is empty", result.isEmpty());
+ Assert.assertEquals("Result size not match", 5, result.size());
+
+ Assert.assertTrue("Key1 not found", result.containsKey(prefix + key1));
+ Assert.assertEquals("Value1 not found", value1, result.get(prefix + key1));
+ Assert.assertTrue("Key2 not found", result.containsKey(prefix + key2));
+ Assert.assertEquals("Value2 not found", value2, result.get(prefix + key2));
+ Assert.assertTrue("Key3 not found", result.containsKey(prefix + key3));
+ Assert.assertEquals("Value3 not found", value3, result.get(prefix + key3));
+ Assert.assertTrue("Key4 not found", result.containsKey(prefix + key4));
+ Assert.assertEquals("Value4 not found", value4, result.get(prefix + key4));
+
+ }
+
+ @Test
+ public void convertListToMapTest_2() {
+ final java.util.List<String> propList = new ArrayList<>();
+
+ final Map<String, String> result = KeyValueUtils.convertListToMap(propList);
+ Assert.assertNotNull("Result is null", result);
+ Assert.assertTrue("Result is not empty", result.isEmpty());
+
+ }
+
+ private Map<String, String> generateTestMap(final String testPrefix, final int entriesWithPrefix,
+ final int entriesWithoutPrefix) {
+ final Map<String, String> result = new HashMap<>();
+ for (int i = 0; i < entriesWithPrefix; i++) {
+ result.put(testPrefix + KeyValueUtils.KEY_DELIMITER + RandomStringUtils.randomAlphabetic(5),
+ RandomStringUtils.randomAlphabetic(5));
+ }
+
+ final String key = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ for (int i = 0; i < entriesWithoutPrefix; i++) {
+ result.put(key + KeyValueUtils.KEY_DELIMITER + RandomStringUtils.randomAlphabetic(5),
+ RandomStringUtils.randomAlphabetic(5));
+ }
+
+ return result;
+
+ }
+
+
+}