Alfresco : Increase document version when overriding file in ftp - ftp

I want to increase minor document version when overriding file in ftp. When I traced the code, ContentDiskDriver2.truncateFile() works for overriding file. Inside this function I use versionService to increase version. Following code is written in truncateFile()
try {
NodeRef nodeRef = getNodeForPath(tree, DriverContent.FILE_OPEN_PARAMS.getPath());
System.out.println("Node Ref: " + nodeRef);
// Increase minor version to file.
Map<String, Serializable> versionProperties = new HashMap<String, Serializable>(2, 1.0f);
versionProperties.put(Version.PROP_DESCRIPTION, "");
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR);
VersionService versionService = (VersionService) applicationContext.getBean("versionService");
versionService.createVersion(nodeRef, versionProperties);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
But unfortunately I got this error.
2013-01-02 14:12:31,609 ERROR [org.alfresco.fileserver] [Sess_FTP3_192.168.1.166] Error from JLAN
org.alfresco.error.AlfrescoRuntimeException: 00020073 Transaction must be active and synchronization is required: Thread[Sess_FTP3_192.168.1.166,5,FTPSessions]
at org.alfresco.repo.transaction.AlfrescoTransactionSupport.registerSynchronizations(AlfrescoTransactionSupport.java:467)
at org.alfresco.repo.transaction.AlfrescoTransactionSupport.getSynchronization(AlfrescoTransactionSupport.java:451)
at org.alfresco.repo.transaction.AlfrescoTransactionSupport.getResource(AlfrescoTransactionSupport.java:244)
at org.alfresco.repo.transaction.TransactionalResourceHelper.incrementCount(TransactionalResourceHelper.java:71)
at org.alfresco.repo.policy.BehaviourFilterImpl.disableBehaviour(BehaviourFilterImpl.java:158)
at org.alfresco.repo.version.Version2ServiceImpl.createVersion(Version2ServiceImpl.java:212)
at org.alfresco.repo.version.Version2ServiceImpl.createVersion(Version2ServiceImpl.java:140)
at org.alfresco.filesys.repo.ContentDiskDriver2.increaseVersion(ContentDiskDriver2.java:2937)
at org.alfresco.filesys.repo.ContentDiskDriver2.truncateFile(ContentDiskDriver2.java:1652)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:196)
at $Proxy97.truncateFile(Unknown Source)
at org.alfresco.filesys.repo.NonTransactionalRuleContentDiskDriver.truncateFile(NonTransactionalRuleContentDiskDriver.java:480)
at org.alfresco.filesys.repo.LegacyFileStateDriver.truncateFile(LegacyFileStateDriver.java:471)
at org.alfresco.filesys.repo.BufferedContentDiskDriver.truncateFile(BufferedContentDiskDriver.java:532)
at org.alfresco.jlan.ftp.FTPSrvSession.procStoreFile(FTPSrvSession.java:2262)
at org.alfresco.jlan.ftp.FTPSrvSession.run(FTPSrvSession.java:4924)
at java.lang.Thread.run(Thread.java:662)
Can you help me how to solve Transaction must be active and synchronization is required
I found this link..
Is the Alfresco repository document version history available via CIFS/FTP?

You've been caught by "little letter" vs "Big Letter" Alfresco services
"little letter" services are the raw services, and normally only used within other Alfresco low level services. "Big Letter" services are the wrapped user facing services, which include transactions, auditing, security etc.
For your case, you need to use the Big Letter form, so change the line
VersionService versionService = (VersionService) applicationContext.getBean("versionService");
To the correct one:
VersionService versionService = (VersionService) applicationContext.getBean("VersionService");
And you'll get a copy of the VersionService with transactions, security etc, which is what I think you need for your situation. (Note that the bean is fetched with a Big First Letter rather than little letter)

This is alternative solution I found. The use of transaction explicitly.
VersionService versionService = (VersionService) applicationContext.getBean("VersionService");
TransactionService transactionService = (TransactionService) applicationContext.getBean("transactionService");
UserTransaction tx = null;
try {
tx = transactionService.getUserTransaction();
tx.begin();
versionService.createVersion(nodeRef, versionProperties);
tx.commit();
}
catch (Exception e)
{
if(tx != null)
{
try
{
tx.rollback();
} catch (IllegalStateException e1)
{
e1.printStackTrace();
} catch (SecurityException e2)
{
e2.printStackTrace();
} catch (SystemException e3)
{
e3.printStackTrace();
}
}
}

Related

Is there a way to batch upload a collection of InputStreams to Amazon S3 using the Java SDK?

I am aware of the TransferManager and the .uploadFileList() and .uploadFileDirectory() methods, however they accept java.io.File types as arguments. I have a collection of byte array input streams containing jpeg image data. I don't want to create in-memory files to store this data before I upload it either.
So what I need is essentially what the S3 client's PutObjectRequest does but for a collection of InputStream objects. Also, if one upload fails, I want to abort the whole thing and not upload anything, much like how a database transaction will reverse the changes if something goes wrong along the way.
Is this possible with the Java SDK?
Before I share an answer, please consider upgrading...
fyi - TransferManager is deprecated, now supported as TransferManagerBuilder in JAVA AWS SDK, please consider upgrading if TransferManagerBuilder Object suits your needs.
now since you asked about TransferManager, you could either 1) copy the code below and replace the functionality/arguments with your custom in memory handling of the input stream and handle it in your custom function... or; 2) further below is another sample, try to use this as-is...
Github source modify with with inputstream and issue listed here
private def uploadFile(is: InputStream, s3ObjectName: String, metadata: ObjectMetadata) = {
try {
val putObjectRequest = new PutObjectRequest(bucketName, s3ObjectName,
is, metadata)
// TransferManager supports asynchronous uploads and downloads
val upload = transferManager.upload(putObjectRequest)
upload.addProgressListener(ExceptionReporter.wrap(UploadProgressListener(putObjectRequest)))
} catch {
case e: Exception => throw new RuntimeException(e)
}
}
Bonus, Nice custom answer here using sequence input streams
public void combineFiles() {
List<String> files = getFiles();
long totalFileSize = files.stream()
.map(this::getContentLength)
.reduce(0L, (f, s) -> f + s);
try {
try (InputStream partialFile = new SequenceInputStream(getInputStreamEnumeration(files))) {
ObjectMetadata resultFileMetadata = new ObjectMetadata();
resultFileMetadata.setContentLength(totalFileSize);
s3Client.putObject("bucketName", "resultFilePath", partialFile, resultFileMetadata);
}
} catch (IOException e) {
LOG.error("An error occurred while combining files. {}", e);
}
}
private Enumeration<? extends InputStream> getInputStreamEnumeration(List<String> files) {
return new Enumeration<InputStream>() {
private Iterator<String> fileNamesIterator = files.iterator();
#Override
public boolean hasMoreElements() {
return fileNamesIterator.hasNext();
}
#Override
public InputStream nextElement() {
try {
return new FileInputStream(Paths.get(fileNamesIterator.next()).toFile());
} catch (FileNotFoundException e) {
System.err.println(e.getMessage());
throw new RuntimeException(e);
}
}
};
}

IText keep pfm file open in Ubuntu

We have a web app running on Tomcat/Ubuntu and using iText7.1.8 to generate pdf documents (Invoices). We noticed that our Tomcat crashed many times and then after investigations found that it was iText the problem. Here is the exception
SEVERE: Socket accept failed
org.apache.tomcat.jni.Error: 24: Too many open files
at org.apache.tomcat.jni.Socket.accept(Native Method)
at org.apache.tomcat.util.net.AprEndpoint$Acceptor.run(AprEndpoint.java:992)
at java.lang.Thread.run(Thread.java:745)
When we run this command: sudo ls -l /proc/Tomcat-PID/fd we notice that most of the files opened are with extension .pfm (ex: /usr/share/fonts/type1/gsfonts/n022004l.pfm) and never released. This number continue to increase till reaches the max number of opened files.
Here is the code in Java used to generate the pdf.
public static File convertToPDF(File pdfFile,URL webURL){
InputStream htmlStream=null;
FileOutputStream pdfStream=null;
try {
htmlStream=webURL.openStream();
pdfStream=new FileOutputStream(pdfFile);
ConverterProperties properties = new ConverterProperties();
properties.setFontProvider(new DefaultFontProvider(true, true, true));
HtmlConverter.convertToPdf(htmlStream, pdfStream,properties);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(htmlStream!= null){
htmlStream.close();
}
if(pdfStream!= null){
pdfStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return pdfFile;
}
Should we use a singleton to avoid multi instance, of this process which generates pdf, and the multiple files opened?
Environment:
Ubuntu 14.04
Tomcat 7.0.52
Java 1.7.0_80-b15
itext 7.1.8
Thank you
Fixed issue.
Use a singleton to get converter properties:
private static ConverterProperties properties;
private static DefaultFontProvider defaultFontProvider;
...
defaultFontProvider= new DefaultFontProvider(true, true, true);
properties.setFontProvider(defaultFontProvider);

Error/Exception while marshalling signed and encrypted response OpenSAML v3

I have been using OpenSaml V2 for a while, which has been working well, and I recently started the migration. Due to the lack of information, even from the OpenSaml V3 book I have recently purchase, I am having some issues with a few things that were working fine with V2.
I have been using the following method to encrypt the Assertion. This method seems to be working fine.
private EncryptedAssertion createEncryptedAssertion(Assertion assertion) throws SamlException {
try {
Credential keyEncryptionCredential = CredentialSupport.getSimpleCredential(this.encryptingCertificate, this.encryptingPrivateKey);
DataEncryptionParameters encryptionParameters = new DataEncryptionParameters();
encryptionParameters.setAlgorithm(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128);
KeyEncryptionParameters keyEncryptionParameters = new KeyEncryptionParameters();
keyEncryptionParameters.setEncryptionCredential(keyEncryptionCredential);
keyEncryptionParameters.setAlgorithm(EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP);
Encrypter samlEncrypter = new Encrypter(encryptionParameters, keyEncryptionParameters);
samlEncrypter.setKeyPlacement(Encrypter.KeyPlacement.INLINE);
return samlEncrypter.encrypt(assertion);
}
catch(Exception e) {
throw new SamlException(e);
}
}
The problem I am having happens when I try to marshall my response with the encrypted assertion, using the following method:
public String marshall(XMLObject xmlObject, boolean encode) throws SamlException {
try {
ParserPool parserPool = XMLObjectProviderRegistrySupport.getParserPool();
MarshallerFactory marshallerFactory = XMLObjectProviderRegistrySupport.getMarshallerFactory();
Marshaller marshaller = marshallerFactory.getMarshaller(xmlObject);
if(marshaller == null) {
throw new SamlException("Unable to locate marshaller for " + xmlObject.getElementQName()
+ " can not perform marshalling operation");
}
Element element = marshallerFactory.getMarshaller(xmlObject).marshall(xmlObject, parserPool.newDocument());
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "3");
StreamResult result = new StreamResult(new StringWriter());
DOMSource source = new DOMSource(element);
transformer.transform(source, result);
String xmlString = result.getWriter().toString();
if(encode) {
//return Util.base64EncodeMessage(xmlString);
}
return xmlString;
}
catch(Exception e) {
throw new SamlException(e);
}
}
When I try to marshall my response with encrypted assertion, I get the following exception:
Caused by: org.opensaml.core.xml.io.MarshallingException: Unable to root namespaces of cached DOM element, {http://www.w3.org/2001/04/xmlenc#}EncryptionMethod
at org.opensaml.core.xml.io.AbstractXMLObjectMarshaller.prepareForAdoption(AbstractXMLObjectMarshaller.java:427)
at org.opensaml.core.xml.io.AbstractXMLObjectMarshaller.marshall(AbstractXMLObjectMarshaller.java:144)
at org.opensaml.core.xml.io.AbstractXMLObjectMarshaller.marshallChildElements(AbstractXMLObjectMarshaller.java:271)
at org.opensaml.core.xml.io.AbstractXMLObjectMarshaller.marshallInto(AbstractXMLObjectMarshaller.java:212)
at org.opensaml.core.xml.io.AbstractXMLObjectMarshaller.marshall(AbstractXMLObjectMarshaller.java:162)
at org.opensaml.core.xml.io.AbstractXMLObjectMarshaller.marshallChildElements(AbstractXMLObjectMarshaller.java:271)
at org.opensaml.core.xml.io.AbstractXMLObjectMarshaller.marshallInto(AbstractXMLObjectMarshaller.java:212)
at org.opensaml.core.xml.io.AbstractXMLObjectMarshaller.marshall(AbstractXMLObjectMarshaller.java:162)
at org.opensaml.core.xml.io.AbstractXMLObjectMarshaller.marshallChildElements(AbstractXMLObjectMarshaller.java:271)
at org.opensaml.core.xml.io.AbstractXMLObjectMarshaller.marshallInto(AbstractXMLObjectMarshaller.java:212)
at org.opensaml.core.xml.io.AbstractXMLObjectMarshaller.marshall(AbstractXMLObjectMarshaller.java:162)
at org.opensaml.core.xml.io.AbstractXMLObjectMarshaller.marshallChildElements(AbstractXMLObjectMarshaller.java:271)
at org.opensaml.core.xml.io.AbstractXMLObjectMarshaller.marshallInto(AbstractXMLObjectMarshaller.java:212)
at org.opensaml.core.xml.io.AbstractXMLObjectMarshaller.marshall(AbstractXMLObjectMarshaller.java:162)
at org.opensaml.saml.common.AbstractSAMLObjectMarshaller.marshall(AbstractSAMLObjectMarshaller.java:65)
at org.opensaml.core.xml.io.AbstractXMLObjectMarshaller.marshallChildElements(AbstractXMLObjectMarshaller.java:271)
at org.opensaml.core.xml.io.AbstractXMLObjectMarshaller.marshallInto(AbstractXMLObjectMarshaller.java:212)
at org.opensaml.core.xml.io.AbstractXMLObjectMarshaller.marshall(AbstractXMLObjectMarshaller.java:118)
at org.opensaml.saml.common.AbstractSAMLObjectMarshaller.marshall(AbstractSAMLObjectMarshaller.java:57)
at com.divinvest.sso.opensaml.SamlAssertionProducerV2.marshall(SamlAssertionProducerV2.java:171)
... 25 more
Caused by: org.w3c.dom.DOMException: Unable to resolve namespace prefix ds found on element {http://www.w3.org/2000/09/xmldsig#}DigestMethod
at net.shibboleth.utilities.java.support.xml.NamespaceSupport.rootNamespaces(NamespaceSupport.java:247)
at net.shibboleth.utilities.java.support.xml.NamespaceSupport.rootNamespaces(NamespaceSupport.java:295)
at net.shibboleth.utilities.java.support.xml.NamespaceSupport.rootNamespaces(NamespaceSupport.java:200)
at org.opensaml.core.xml.io.AbstractXMLObjectMarshaller.prepareForAdoption(AbstractXMLObjectMarshaller.java:422)
... 44 more
Am I missing anything in the unmarshall method? I am marshall my response objects with signed assertion, signed response but when the assertion is encrypted, I am not able to.
Thank you
The issue was that xmltooling was bringing the wrong xmlsec version (1.5.7), I had to include an exclusing in order to use xmlsec 2.0.5 that is using by opensaml-security-api.

How to get rid of NullPointerException in Flume Interceptor?

I have an interceptor written for Flume code is below:
public Event intercept(Event event) {
byte[] xmlstr = event.getBody();
InputStream instr = new ByteArrayInputStream(xmlstr);
//TransformerFactory factory = TransformerFactory.newInstance(TRANSFORMER_FACTORY_CLASS,TRANSFORMER_FACTORY_CLASS.getClass().getClassLoader());
TransformerFactory factory = TransformerFactory.newInstance();
Source xslt = new StreamSource(new File("removeNs.xslt"));
Transformer transformer = null;
try {
transformer = factory.newTransformer(xslt);
} catch (TransformerConfigurationException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Source text = new StreamSource(instr);
OutputStream ostr = new ByteArrayOutputStream();
try {
transformer.transform(text, new StreamResult(ostr));
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
event.setBody(ostr.toString().getBytes());
return event;
}
I'm removing NameSpace from my source xml with removeNs.xslt file. So that I can store that data into HDFS and later put into hive. When my interceptor run it throw below error :
ERROR org.apache.flume.source.jms.JMSSource: Unexpected error processing events
java.lang.NullPointerException
at test.intercepter.App.intercept(App.java:59)
at test.intercepter.App.intercept(App.java:82)
at org.apache.flume.interceptor.InterceptorChain.intercept(InterceptorChain.java:62)
at org.apache.flume.channel.ChannelProcessor.processEventBatch(ChannelProcessor.java:146)
at org.apache.flume.source.jms.JMSSource.doProcess(JMSSource.java:258)
at org.apache.flume.source.AbstractPollableSource.process(AbstractPollableSource.java:54)
at org.apache.flume.source.PollableSourceRunner$PollingRunner.run(PollableSourceRunner.java:139)
at java.lang.Thread.run(Thread.java:745)*
Can you suggest me what and where is the problem?
I found the solution. The problem was not anything else than new File("removeNs.xslt"). It was not able to find the location as I's not sure where to keep this file but later I get the flume agent path but as soon as I restart the flume agent it deletes all files which I kept in the flume agent dir. So I changed the code and kept the file material into my java code.

How to close refcursor in spring when using simplejdbccall

I am using spring simpleJdbcCall to call oracle stored procedure and i am using oracle 11g .
I stumbled on a couple of posts which suggests there might be memory leak as the ref cursors are not properly closed by spring.
Is there anyway to explicitly close cursor while using spring simplejdbccall? or is increasing the oracle OPEN_CURSOR the only way out?.
I am planning to scale up my application to handle around one million transactions every hour .Any suggestions will be helpful.
Actually there is no such an issue with Spring JDBC. It closes all resources within finally after all execute. SimpleJdbcCall uses JdbcTemplate:
public <T> T execute(CallableStatementCreator csc, CallableStatementCallback<T> action)
throws DataAccessException {
try {
...
}
catch (SQLException ex) {
...
}
finally {
if (csc instanceof ParameterDisposer) {
((ParameterDisposer) csc).cleanupParameters();
}
JdbcUtils.closeStatement(cs);
DataSourceUtils.releaseConnection(con, getDataSource());
}
}
The same for ResultSet OUT parameters:
protected Map<String, Object> processResultSet(ResultSet rs, ResultSetSupportingSqlParameter param) throws SQLException {
....
finally {
JdbcUtils.closeResultSet(rs);
}
return returnedResults;
}
From other side I have a big experience with Spring JDBC and Oracle in high-loaded systems and want to say that we noticed enough open resources on Oracle with at peak loads, but they have been released properly after that.
Although we used JBOSS Pooled DataSource and its TransactionMaanger
I use CallableStatement directly and I can release statements and connections quickly and safely, try both methods and measure memory consumption, it worked perfectly for me to solve memory consumption and connection retention problems that proved many waiting and rejection of connections the applications.
try {
log.info("**** RepositoryPSostgres.getAllProducts ******** ");
Connection conn = jdbcTemplate.getDataSource().getConnection();
conn.setAutoCommit(false);
// Procedure call.
CallableStatement proc = conn.prepareCall("{? = call get_all_products() }");
proc.registerOutParameter(1, Types.OTHER);
proc.execute();
ResultSet results = (ResultSet) proc.getObject(1);
**proc.close();
proc.isClosed();
conn.close();**
ArrayList <Products> resp = new ArrayList <Products>();
while (results.next()) {
Products resp1 = new Products();
resp1.setId(results.getInt("id"));
resp1.setName((String) results.getString("name"));
resp1.setPrice((BigDecimal) results.getBigDecimal("price"));
resp.add(resp1);
log.info("***" + results.getInt("id") + "***** ");
log.info("***" + results.getString("name") + "***** ");
log.info("***" + results.getBigDecimal("price") + "***** ");
}
results.close();
return resp;
} catch (Exception e) {
e.printStackTrace();
log.error(new StringBuffer("Error en transaccion en saldo CashPooling : ").append(e.getLocalizedMessage()).toString());
return null;
}

Resources