-
Notifications
You must be signed in to change notification settings - Fork 79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merge CheckSumPipe and HashPipe and add hashEncoding #7456
Merged
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
3220799
Unit tests and documentation
evandongen fd0e137
Review comments
evandongen 5503c6c
Review comments
evandongen eb4f759
Refactor the pipes to one pipe
evandongen 5d17189
Prepare review
evandongen 6df5f6b
Fix copyrights
evandongen 3b3c6de
Fixed set type larva issue for backwards compatibility
evandongen dd5619b
Review comments
evandongen File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
/* | ||
Copyright 2013, 2020 Nationale-Nederlanden, 2020, 2022 WeAreFrank! | ||
Copyright 2013, 2020 Nationale-Nederlanden, 2020-2024 WeAreFrank! | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
|
@@ -16,163 +16,74 @@ | |
package org.frankframework.pipes; | ||
|
||
import java.io.FileInputStream; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.math.BigInteger; | ||
import java.security.MessageDigest; | ||
import java.security.NoSuchAlgorithmException; | ||
import java.util.zip.Adler32; | ||
import java.util.zip.CRC32; | ||
import java.util.zip.Checksum; | ||
|
||
import lombok.Getter; | ||
|
||
import org.frankframework.configuration.ConfigurationException; | ||
import org.frankframework.configuration.ConfigurationWarning; | ||
import org.frankframework.core.PipeLineSession; | ||
import org.frankframework.core.PipeRunException; | ||
import org.frankframework.core.PipeRunResult; | ||
import org.frankframework.pipes.hash.Algorithm; | ||
import org.frankframework.stream.Message; | ||
|
||
/** | ||
* Pipe to calculate checksum on input. | ||
* | ||
* This pipe can be used to generate a hash for the given message using an algorithm. With this, you can prove integrity of the message. If you | ||
* need to prove the authenticity of the message as well, please use the {@link HashPipe} which uses an algorithm and a secret to prove both | ||
* integrity and authenticity. | ||
* <p> | ||
* The hash is generated based on the bytes of the given input message or on the bytes read from the file path if @{code inputIsFile} is @{code true} | ||
* <p> | ||
* The supported algorithms are: | ||
* <ul> | ||
* <li>CRC32</li> | ||
* <li>Adler32</li> | ||
* <li>MD5</li> | ||
* <li>SHA</li> | ||
* <li>SHA256</li> | ||
* <li>SHA384</li> | ||
* <li>SHA512</li> | ||
* </ul> | ||
* | ||
* @author Gerrit van Brakel | ||
* @since 4.9 | ||
* @author Gerrit van Brakel | ||
* @since 4.9 | ||
* @deprecated please use the {@link HashPipe} | ||
*/ | ||
public class ChecksumPipe extends FixedForwardPipe { | ||
@Deprecated(forRemoval = true, since = "8.3.0") | ||
@ConfigurationWarning("Use the HashPipe") | ||
public class ChecksumPipe extends HashPipe { | ||
|
||
private @Getter String charset; | ||
private @Getter ChecksumType type=ChecksumType.MD5; | ||
private @Getter boolean inputIsFile; | ||
|
||
public enum ChecksumType { | ||
MD5, | ||
SHA, | ||
SHA256("SHA-256"), | ||
SHA512("SHA-512"), | ||
CRC32, | ||
ADLER32; | ||
|
||
private final String algorithm; | ||
|
||
ChecksumType(String algorithm) { | ||
this.algorithm = algorithm; | ||
} | ||
ChecksumType() { | ||
this(null); | ||
} | ||
|
||
public String getAlgorithm() { | ||
return algorithm!=null ? algorithm : name(); | ||
} | ||
} | ||
|
||
protected interface ChecksumGenerator { | ||
void update(int b); | ||
void update(byte[] b, int offset, int length); | ||
String getResult(); | ||
} | ||
|
||
protected ChecksumGenerator createChecksumGenerator() throws NoSuchAlgorithmException { | ||
switch(getType()) { | ||
case MD5: | ||
case SHA: | ||
case SHA256: | ||
case SHA512: | ||
return new MessageDigestChecksumGenerator(getType()); | ||
case CRC32: | ||
return new ZipChecksumGenerator(new CRC32()); | ||
case ADLER32: | ||
return new ZipChecksumGenerator(new Adler32()); | ||
default: | ||
throw new NoSuchAlgorithmException("unsupported algorithm ["+getType()+"]"); | ||
} | ||
} | ||
|
||
protected static class ZipChecksumGenerator implements ChecksumGenerator { | ||
|
||
private final Checksum checksum; | ||
|
||
ZipChecksumGenerator(Checksum checksum) { | ||
super(); | ||
this.checksum=checksum; | ||
checksum.reset(); | ||
} | ||
|
||
@Override | ||
public void update(int b){ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Deze werd nergens gebruikt |
||
checksum.update(b); | ||
} | ||
|
||
@Override | ||
public void update(byte[] b, int offset, int length){ | ||
checksum.update(b,offset,length); | ||
} | ||
|
||
@Override | ||
public String getResult(){ | ||
return Long.toHexString(checksum.getValue()); | ||
} | ||
} | ||
|
||
protected static class MessageDigestChecksumGenerator implements ChecksumGenerator { | ||
|
||
private final MessageDigest messageDigest; | ||
|
||
MessageDigestChecksumGenerator(ChecksumType type) throws NoSuchAlgorithmException { | ||
super(); | ||
this.messageDigest=MessageDigest.getInstance(type.getAlgorithm()); | ||
} | ||
|
||
@Override | ||
public void update(int b){ | ||
messageDigest.update((byte)b); | ||
@Override | ||
public void configure() throws ConfigurationException { | ||
// Set the defaults for this Pipe, these are different compared to the HashPipe | ||
if (getAlgorithm() == null) { | ||
setAlgorithm(Algorithm.MD5); | ||
} | ||
|
||
@Override | ||
public void update(byte[] b, int offset, int length){ | ||
messageDigest.update(b,offset,length); | ||
if (getHashEncoding() == null) { | ||
setHashEncoding(HashPipe.HashEncoding.Hex); | ||
} | ||
|
||
@Override | ||
public String getResult(){ | ||
return new BigInteger(1,messageDigest.digest()).toString(16); | ||
} | ||
super.configure(); | ||
} | ||
|
||
@Override | ||
public PipeRunResult doPipe(Message message, PipeLineSession session) throws PipeRunException { | ||
try { | ||
ChecksumGenerator cg=createChecksumGenerator(); | ||
byte[] barr=new byte[1000]; | ||
try (InputStream fis = isInputIsFile() ? new FileInputStream(message.asString()) : message.asInputStream(getCharset())){ | ||
int c; | ||
while ((c=fis.read(barr))>=0) { | ||
cg.update(barr, 0, c); | ||
} | ||
} | ||
return new PipeRunResult(getSuccessForward(), cg.getResult()); | ||
} catch (Exception e) { | ||
throw new PipeRunException(this,"cannot calculate ["+getType()+"]"+(isInputIsFile()?" on file ["+message+"]":" using charset ["+getCharset()+"]"),e); | ||
} | ||
} | ||
|
||
/** | ||
* Character encoding to be used to encode message before calculating checksum. | ||
*/ | ||
public void setCharset(String string) { | ||
charset = string; | ||
} | ||
try (InputStream fis = isInputIsFile() ? new FileInputStream(message.asString()) : message.asInputStream(getCharset())) { | ||
|
||
/** | ||
* Type of checksum to be calculated | ||
* @ff.default MD5 | ||
*/ | ||
public void setType(ChecksumType value) { | ||
type = value; | ||
return super.doPipe(new Message(fis, message.getContext()), session); | ||
} catch (IOException e) { | ||
throw new PipeRunException(this, "Error reading input" + (isInputIsFile() ? " file [" + message + "]" : " using charset [" + getCharset() + "]"), e); | ||
} | ||
} | ||
|
||
/** | ||
* If set <code>true</code>, the input is assumed to be a filename; otherwise the input itself is used in the calculations. | ||
* | ||
* @ff.default false | ||
*/ | ||
@Deprecated(forRemoval = true, since = "7.7.0") | ||
|
@@ -181,4 +92,13 @@ public void setInputIsFile(boolean b) { | |
inputIsFile = b; | ||
} | ||
|
||
/** | ||
* Type of checksum to be calculated | ||
* @ff.default MD5 | ||
*/ | ||
@Deprecated(forRemoval = true, since = "8.3.0") | ||
@ConfigurationWarning("Please use setAlgorithm to set the algorithm") | ||
public void setType(Algorithm value) { | ||
setAlgorithm(value); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,7 +20,10 @@ | |
|
||
import javax.xml.transform.TransformerException; | ||
|
||
import lombok.Getter; | ||
import org.apache.commons.lang3.StringUtils; | ||
import org.xml.sax.SAXException; | ||
|
||
import org.frankframework.configuration.ConfigurationException; | ||
import org.frankframework.configuration.ConfigurationWarning; | ||
import org.frankframework.core.ParameterException; | ||
|
@@ -40,9 +43,6 @@ | |
import org.frankframework.util.ClassLoaderUtils; | ||
import org.frankframework.util.StringResolver; | ||
import org.frankframework.util.TransformerPool; | ||
import org.xml.sax.SAXException; | ||
|
||
import lombok.Getter; | ||
|
||
/** | ||
* This Pipe opens and returns a file from the classpath. The filename is a mandatory parameter to use. You can | ||
|
@@ -80,7 +80,7 @@ | |
* <pipe name="make unique message" className="org.frankframework.pipes.FixedResultPipe" | ||
* returnString="<msg mid="MID" action="ACTION" />" replaceFixedParams="true"> | ||
* <param name="MID" sessionKey="mid" /> | ||
* <param name="ACTION" xpathExpression="request/@action" /> | ||
* <param name="ACTION" xpathExpression="request/@action" /> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Formatting fix voor wat we vanochtend zagen |
||
* </pipe> | ||
* } | ||
* </pre> | ||
|
@@ -90,8 +90,8 @@ | |
* {@code | ||
* <pipe name="make unique message" className="org.frankframework.pipes.ReplacerPipe" | ||
* getInputFromFixedValue="<msg mid="?{MID}" action="?{ACTION}" />"> | ||
* <param name="MID" sessionKey="mid" /> | ||
* <param name="ACTION" xpathExpression="request/@action" /> | ||
* <param name="MID" sessionKey="mid" /> | ||
* <param name="ACTION" xpathExpression="request/@action" /> | ||
* </pipe> | ||
* } | ||
* </pre> | ||
|
@@ -128,59 +128,59 @@ | |
* was also used to store information in the session. For example, a port of configuration in the JMS listener sender configuration looked like this: | ||
* <pre> | ||
* {@code | ||
* <CompareStringPipe name="compareIdAndCid" > | ||
* <param name="operand1" sessionKey="id"/> | ||
* <param name="operand2" sessionKey="cid"/> | ||
* <forward name="equals" path="IdAndCidSame" /> | ||
* <forward name="lessthan" path="IdAndCidDifferent" /> | ||
* <forward name="greaterthan" path="IdAndCidDifferent" /> | ||
* </CompareStringPipe> | ||
* <FixedResultPipe name="IdAndCidSame" returnString="true" storeResultInSessionKey="IdAndCidSame"> | ||
* <forward name="success" path="displayKeys" /> | ||
* </FixedResultPipe> | ||
* <FixedResultPipe name="IdAndCidDifferent" returnString="false" storeResultInSessionKey="IdAndCidSame"> | ||
* <forward name="success" path="displayKeys" /> | ||
* </FixedResultPipe> | ||
* <CompareStringPipe name="compareIdAndCid" > | ||
* <param name="operand1" sessionKey="id"/> | ||
* <param name="operand2" sessionKey="cid"/> | ||
* <forward name="equals" path="IdAndCidSame" /> | ||
* <forward name="lessthan" path="IdAndCidDifferent" /> | ||
* <forward name="greaterthan" path="IdAndCidDifferent" /> | ||
* </CompareStringPipe> | ||
* <FixedResultPipe name="IdAndCidSame" returnString="true" storeResultInSessionKey="IdAndCidSame"> | ||
* <forward name="success" path="displayKeys" /> | ||
* </FixedResultPipe> | ||
* <FixedResultPipe name="IdAndCidDifferent" returnString="false" storeResultInSessionKey="IdAndCidSame"> | ||
* <forward name="success" path="displayKeys" /> | ||
* </FixedResultPipe> | ||
* | ||
* <pipe name="displayKeys" className="org.frankframework.pipes.FixedResultPipe" | ||
* returnString="branch [BRANCH] Orignal Id [MID] cid [CID] id=cid [SAME]" replaceFixedParams="true"> | ||
* <param name="BRANCH" sessionKey="originalMessage" xpathExpression="*/@branch" /> | ||
* <param name="MID" sessionKey="id" /> | ||
* <param name="CID" sessionKey="cid" /> | ||
* <param name="SAME" sessionKey="IdAndCidSame" /> | ||
* <forward name="success" path="EXIT" /> | ||
* </pipe> | ||
* <pipe name="displayKeys" className="org.frankframework.pipes.FixedResultPipe" | ||
* returnString="branch [BRANCH] Orignal Id [MID] cid [CID] id=cid [SAME]" replaceFixedParams="true"> | ||
* <param name="BRANCH" sessionKey="originalMessage" xpathExpression="*/@branch" /> | ||
* <param name="MID" sessionKey="id" /> | ||
* <param name="CID" sessionKey="cid" /> | ||
* <param name="SAME" sessionKey="IdAndCidSame" /> | ||
* <forward name="success" path="EXIT" /> | ||
* </pipe> | ||
* } | ||
* </pre> | ||
* | ||
* Was rewritten to the following: | ||
* <pre> | ||
* {@code | ||
* <CompareStringPipe name="compareIdAndCid" > | ||
* <param name="operand1" sessionKey="id"/> | ||
* <param name="operand2" sessionKey="cid"/> | ||
* <forward name="equals" path="IdAndCidSame" /> | ||
* <forward name="lessthan" path="IdAndCidDifferent" /> | ||
* <forward name="greaterthan" path="IdAndCidDifferent" /> | ||
* </CompareStringPipe> | ||
* <CompareStringPipe name="compareIdAndCid" > | ||
* <param name="operand1" sessionKey="id"/> | ||
* <param name="operand2" sessionKey="cid"/> | ||
* <forward name="equals" path="IdAndCidSame" /> | ||
* <forward name="lessthan" path="IdAndCidDifferent" /> | ||
* <forward name="greaterthan" path="IdAndCidDifferent" /> | ||
* </CompareStringPipe> | ||
* | ||
* <PutInSessionPipe name="IdAndCidSame" value="true" sessionKey="IdAndCidSame"> | ||
* <forward name="success" path="putOriginalMessageInSession" /> | ||
* </PutInSessionPipe> | ||
* <PutInSessionPipe name="IdAndCidDifferent" value="false" sessionKey="IdAndCidSame"> | ||
* <forward name="success" path="putOriginalMessageInSession" /> | ||
* </PutInSessionPipe> | ||
* <PutInSessionPipe name="IdAndCidSame" value="true" sessionKey="IdAndCidSame"> | ||
* <forward name="success" path="putOriginalMessageInSession" /> | ||
* </PutInSessionPipe> | ||
* <PutInSessionPipe name="IdAndCidDifferent" value="false" sessionKey="IdAndCidSame"> | ||
* <forward name="success" path="putOriginalMessageInSession" /> | ||
* </PutInSessionPipe> | ||
* | ||
* <PutInSessionPipe name="putOriginalMessageInSession" sessionKey="incomingMessage"/> | ||
* <PutInSessionPipe name="putOriginalMessageInSession" sessionKey="incomingMessage"/> | ||
* | ||
* <pipe name="displayKeys" className="org.frankframework.pipes.ReplacerPipe" | ||
* getInputFromFixedValue="branch [?{BRANCH}] Original Id [?{MID}] cid [?{CID}] id=cid [?{SAME}]"> | ||
* <param name="BRANCH" sessionKey="originalMessage" xpathExpression="*/@branch" /> | ||
* <param name="MID" sessionKey="id" /> | ||
* <param name="CID" sessionKey="cid" /> | ||
* <param name="SAME" sessionKey="IdAndCidSame" /> | ||
* <forward name="success" path="EXIT" /> | ||
* </pipe> | ||
* <pipe name="displayKeys" className="org.frankframework.pipes.ReplacerPipe" | ||
* getInputFromFixedValue="branch [?{BRANCH}] Original Id [?{MID}] cid [?{CID}] id=cid [?{SAME}]"> | ||
* <param name="BRANCH" sessionKey="originalMessage" xpathExpression="*/@branch" /> | ||
* <param name="MID" sessionKey="id" /> | ||
* <param name="CID" sessionKey="cid" /> | ||
* <param name="SAME" sessionKey="IdAndCidSame" /> | ||
* <forward name="success" path="EXIT" /> | ||
* </pipe> | ||
* } | ||
* </pre> | ||
* <p> | ||
|
@@ -246,6 +246,7 @@ public class FixedResultPipe extends FixedForwardPipe { | |
* If a filename or filenameSessionKey was specified, the contents of the file is put in the | ||
* <code>returnString</code>, so that the <code>returnString</code> | ||
* may always be returned. | ||
* | ||
* @throws ConfigurationException | ||
*/ | ||
@Override | ||
|
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Als ik dit zo terugzie is het eigenlijk helemaal niet zo lastig om van deze 2 pipes 1 te maken. Misschien toch maandag even in de groep gooien?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, ik heb de rest aangepast