3

We are trying to upload an image using SDL Tridions SOAP API using Apache's Java CXF. And we are stuck during the creation of a component data component with binary content with this error message:

com.sdltridion.contentmanager.coreservice._2013.ICoreServiceSaveCoreServiceFaultFaultFaultMessage: 

Invalid value for property 'Filename'. Property Filename value is unknown.

As we can tell from the code below, the Filename property is actually set and also available in the SOAP request. What can be the reason for this error message?

This is the actual SOAP request being sent to Tridion:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<Save xmlns="http://www.sdltridion.com/ContentManager/CoreService/2013" xmlns:ns2="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:ns3="http://www.sdltridion.com/ContentManager/R6" xmlns:ns4="http://www.sdltridion.com/Security" xmlns:ns5="http://schemas.microsoft.com/2003/10/Serialization/">
  <deltaData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns3:ComponentData">
    <ns3:BluePrintInfo>
      <ns3:IsLocalized>false</ns3:IsLocalized>
      <ns3:IsShared>false</ns3:IsShared>
      <ns3:LinkToRepositoryData>
        <ns3:IdRef>tcm:0-5-1</ns3:IdRef>
        <ns3:Title>200 Master Content (ENG)</ns3:Title>
      </ns3:LinkToRepositoryData>
    </ns3:BluePrintInfo>
    <ns3:IsPublishedInContext>false</ns3:IsPublishedInContext>
    <ns3:LocationInfo>
      <ns3:RepositoryData xsi:type="ns3:LinkToRepositoryData">
        <ns3:IdRef>tcm:0-5-1</ns3:IdRef>
        <ns3:Title>200 Master Content (ENG)</ns3:Title>
      </ns3:RepositoryData>
      <ns3:OrganizationalItem>
        <ns3:IdRef>tcm:5-3584-2</ns3:IdRef>
        <ns3:Title>Archive</ns3:Title>
      </ns3:OrganizationalItem>
      <ns3:Path>\200 Master Content (ENG)\Building Blocks\Test\Multimedia\Images\Archive</ns3:Path>
      <ns3:WebDavUrl>/webdav/200%20Master%20Content%20(ENG)/Building%20Blocks/Test/Multimedia/Images/Archive/</ns3:WebDavUrl>
    </ns3:LocationInfo>
    <ns3:Metadata/>
    <ns3:ApprovalStatus>
      <ns3:IdRef>tcm:0-0-0</ns3:IdRef>
      <ns3:Title>Undefined</ns3:Title>
    </ns3:ApprovalStatus>
    <ns3:BinaryContentData>
      <ns3:FileSize>5425</ns3:FileSize>
      <ns3:Filename>Hydrangeas.jpg</ns3:Filename>
      <ns3:IsExternal>false</ns3:IsExternal>
      <ns3:LinkToMultimediaTypeData>
        <ns3:IdRef>tcm:0-2-65544</ns3:IdRef>
        <ns3:Title>Jpeg image</ns3:Title>
      </ns3:LinkToMultimediaTypeData>
      <ns3:UploadFromFile>C:\Windows\TEMP\tmp1AB8.jpg</ns3:UploadFromFile>
      <ns3:MimeType>image/jpeg</ns3:MimeType>
    </ns3:BinaryContentData>
    <ns3:ComponentType>Multimedia</ns3:ComponentType>
    <ns3:IsBasedOnMandatorySchema>false</ns3:IsBasedOnMandatorySchema>
    <ns3:IsBasedOnTridionWebSchema>true</ns3:IsBasedOnTridionWebSchema>
    <ns3:Schema>
      <ns3:IdRef>tcm:5-153-8</ns3:IdRef>
      <ns3:Title>Default Multimedia Schema</ns3:Title>
    </ns3:Schema>
  </deltaData>
  <readBackOptions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns3:SynchronizeOptions"/>
</Save>

Any idea about what this error message might actually mean ('Property Filename value is unknown')?

Below is the actual SOAP response coming from Tridion:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
  <faultcode xmlns:a="http://www.sdltridion.com/ContentManager/CoreService/2013">a:InvalidPropertyValueException</faultcode>
  <faultstring xml:lang="en-US">Invalid value for property 'Filename'. Property Filename value is unknown.</faultstring>
  <detail>
    <CoreServiceFault xmlns="http://www.sdltridion.com/ContentManager/R6" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
      <Category>Validation</Category>
      <ErrorCode>ElementNotFound</ErrorCode>
      <ExceptionName>InvalidPropertyValueException</ExceptionName>
      <Messages>
        <Message>Invalid value for property 'Filename'. Property Filename value is unknown.</Message>
      </Messages>
    </CoreServiceFault>
  </detail>
</s:Fault>

This is the error I see in the Tridion Event viewer:

Invalid value for property 'Filename'. Property Filename value is unknown.
Component: Tridion.ContentManager.CoreService
Errorcode: 777
User: NT AUTHORITY\NETWORK SERVICE

StackTrace Information Details:
   at Tridion.ContentManager.ContentManagement.BinaryContent.AssertValidProperties(IEnumerable`1 allowedMultiMediaTypes, Boolean changedToInternalBinaryContent)
   at Tridion.ContentManager.ContentManagement.Component.OnSaving(SaveEventArgs eventArgs)
   at Tridion.ContentManager.IdentifiableObject.Save(SaveEventArgs eventArgs)
   at Tridion.ContentManager.ContentManagement.VersionedItem.Save(Boolean checkInAfterSave)
   at Tridion.ContentManager.ContentManagement.VersionedItem.Save()
   at Tridion.ContentManager.CoreService.CoreServiceBase.Save(IdentifiableObjectData deltaData, ReadOptions readBackOptions)
   at SyncInvokeSave(Object , Object[] , Object[] )
   at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
   at Tridion.ContentManager.CoreService.CoreServiceInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

Project Setup

We have generated the Java client files using the WSDL using CXF's codegin plugin:

        <plugin>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-codegen-plugin</artifactId>
            <version>${cxf.version}</version>
            <executions>
                <execution>
                    <id>generate-sources</id>
                    <phase>generate-sources</phase>
                    <configuration>
                        <sourceRoot>${project.build.directory}/generated-sources/cxf</sourceRoot>
                        <wsdlOptions>
                            <wsdlOption>
                                <wsdl>http://${cms.system}/webservices/CoreService2013.svc?wsdl</wsdl>
                                <wsdlLocation>http://${cms.system}/webservices/CoreService2013.svc?wsdl</wsdlLocation>
                            </wsdlOption>
                        </wsdlOptions>
                    </configuration>
                    <goals>
                        <goal>wsdl2java</goal>
                    </goals>
                </execution>

            </executions>
        </plugin>

This works fine. Then we instantiated the implementation of the ICoreService using this code:

private ICoreService createICoreService(String address, String username, String password) {

    JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();

    addInterceptors(factory);

    factory.setServiceClass(ICoreService.class);
    factory.setAddress(address);

    ICoreService iCoreService = (ICoreService) factory.create();
    activateAuthentication(username, password);

    return iCoreService;
}

...

private void authenticateNtlm(final String username, final String password) {
    class MyAuthenticator extends Authenticator {
        public PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(username, password.toCharArray());
        }
    }
    Authenticator.setDefault(new MyAuthenticator());
}

We also instantiate the CoreService2013 class like so:

@Bean(name = "coreService2013")
public CoreService2013 getService() {
    try {
        return new CoreService2013(new URL(coreServiceAddress));
    } catch (MalformedURLException e) {
        throw new IllegalArgumentException(e);
    }
}

This setup seems to work, since we manage to retrieve information from Tridion and are also able to write ComponentData to Tridion.

Here is an example of a test which runs fine with our setup:

public class ICoreServicesConfigTest {

private ICoreService iCoreService;

@Before
public void setUp() throws Exception {
    AnnotationConfigApplicationContext beanFactory = new AnnotationConfigApplicationContext(ICoreServicesConfig.class);
    iCoreService = (ICoreService) beanFactory.getBean("iCoreService");
}

@Test
public void whenUseICoreService_ShouldRetrieveApplicationIds() throws ICoreServiceGetApplicationIdsCoreServiceFaultFaultFaultMessage {
    ArrayOfstring res = iCoreService.getApplicationIds();
    List<String> strings = res.getString();
    assertThat(strings, is(not(nullValue())));
    assertThat(strings.isEmpty(), is(false));
    for (String id : strings) {
        System.out.println(id);
    }
}
}

Now this is what we did not manage to get working yet: we are trying to upload an image and then create a ComponentData with binary content. As we have understood we need to:

  1. upload the data
  2. create the component data with the binary content.

The first item seems to be working even though we are facing challenges with the 16KB limit mentioned in this blog

Here is the code for uploading the data:

private File uploadFile(File file) throws IOException, IStreamUploadUploadBinaryByteArrayCoreServiceFaultFaultFaultMessage {

    byte[] fileData = new byte[(int) file.length()];
    CoreService2013 coreService2013 = new CoreService2013();

    DataInputStream dis = new DataInputStream(new FileInputStream(file));
    dis.readFully(fileData);
    dis.close();
    IStreamUpload clientUpload = coreService2013.getStreamUploadBasicHttp();
    String uploadFile = clientUpload.uploadBinaryByteArray(file.getName(), fileData);
    return new File(uploadFile);

}

And this is the code for the ComponentData creation:

@Test
public void whenUseICoreService_ShouldCreateTridionImageComponent() throws ICoreServiceGetApplicationIdsCoreServiceFaultFaultFaultMessage,
        ICoreServiceReadCoreServiceFaultFaultFaultMessage, ICoreServiceSaveCoreServiceFaultFaultFaultMessage, ICoreServiceCheckInCoreServiceFaultFaultFaultMessage,
        ClassNotFoundException, IOException, IStreamUploadUploadBinaryByteArrayCoreServiceFaultFaultFaultMessage {
    ComponentData data = new ComponentData();
    ObjectFactory objectFactory = new ObjectFactory();
    setSchema(data, objectFactory, "tcm:5-153-8", "Default Multimedia Schema");
    createApprovalStatusData(data, objectFactory);
    JAXBElement<BinaryContentData> binaryContentData = objectFactory.createBinaryContentData(getBinaryContentData(objectFactory));

    data.setBinaryContent(binaryContentData);

    data.setComponentType(objectFactory.createComponentType(ComponentType.MULTIMEDIA));
    data.setIsBasedOnMandatorySchema(objectFactory.createComponentDataIsBasedOnMandatorySchema(false));
    data.setIsBasedOnTridionWebSchema(objectFactory.createComponentDataIsBasedOnTridionWebSchema(true));
    data.setIsPublishedInContext(objectFactory.createRepositoryLocalObjectDataIsPublishedInContext(false));
    setBluePrintInfo(data, objectFactory);
    setLocationInfo(data, objectFactory, "\\200 Master Content (ENG)\\Building Blocks\\Test\\Multimedia\\Images\\Archive",
            "/webdav/200%20Master%20Content%20(ENG)/Building%20Blocks/Test/Multimedia/Images/Archive/");
    data.setMetadata(objectFactory.createRepositoryLocalObjectDataMetadata(""));
    IdentifiableObjectData res = iCoreService.save(data, objectFactory.createReadOptions());
    assertThat(res, is(not(nullValue())));

}

private BinaryContentData getBinaryContentData(ObjectFactory objectFactory) throws IOException, IStreamUploadUploadBinaryByteArrayCoreServiceFaultFaultFaultMessage {
    BinaryContentData binaryContentData = objectFactory.createBinaryContentData();

    File localFile = LOCAL_FILE;
    File remoteFile = uploadFile(localFile);

    binaryContentData.setFilename(objectFactory.createBinaryDataFilename(LOCAL_FILE.getName()));
    binaryContentData.setFileSize(objectFactory.createBinaryContentDataFileSize((int) LOCAL_FILE.length()));
    binaryContentData.setUploadFromFile(objectFactory.createBinaryContentDataUploadFromFile(remoteFile.getAbsolutePath()));

    LinkToMultimediaTypeData linkToMultimediaTypeData = objectFactory.createLinkToMultimediaTypeData();
    linkToMultimediaTypeData.setIdRef(objectFactory.createLinkIdRef("tcm:0-2-65544"));
    linkToMultimediaTypeData.setTitle(objectFactory.createLinkTitle("Jpeg image"));
    binaryContentData.setMultimediaType(objectFactory.createLinkToMultimediaTypeData(linkToMultimediaTypeData));
    binaryContentData.setMimeType(objectFactory.createBinaryContentDataMimeType("image/jpeg"));
    return binaryContentData;
}
8
  • You are giving a lot of information, but I seem to miss the single point where this fails. Does your uploadFile(file) call work now or not? If that one doesn't work, then all the additional code is obfuscating the question I would say (so it would make sense to edit the question and remove it). Commented Apr 6, 2016 at 12:25
  • Actually the uploadFile(File) method is working fine. I have checked on the physical machine where Tridion is running and the image files have been saved in the C:\Windows\Temp folder.
    – gil.fernandes
    Commented Apr 6, 2016 at 13:25
  • Then I'm really confused to the text in your question since you mentioned that what you didn't get working yet? Maybe you should edit your question and start with explaining what code you run that results in the error. The from there on provide the additional details. Keep in mind that if your question is unclear to the community, you probably won't get a good answer. I like that you are providing additional information, but less is more 😉 Commented Apr 6, 2016 at 13:29
  • Let me clarify. I am performing 2 steps: upload the data, create the component data with the binary content. The first step works, the second not.
    – gil.fernandes
    Commented Apr 6, 2016 at 14:50
  • Are your CM servers load balanced, and is the service connecting to a specific server? Commented Apr 8, 2016 at 13:05

1 Answer 1

3

I did it!! Don't use JAXBElement <> syntax.

Take a look in: http://yatb.mitza.net/2012/12/a-core-service-java-client.html?m=1

Use: wsimport.exe -d c:\temp\gendir -s c:\temp\srcdir -b c:\temp\custombindings.xml -verbose http://t2011sp1hr1.playground/webservices/CoreService2011.svc?wsdl

2
  • Thank you for this. I am not quite clear why there should be a problem with the JAXBElement syntax. Possibly the problem is that Apache CXF has a different implementation than the Metro implementation which is bundled in Java SE. Commented Jun 27, 2016 at 7:12
  • I'm not quite clear too!!!, but now my code is pretty clear, perhaps some kind of unserialization problem Commented Jun 27, 2016 at 21:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.