Last Day

So today is my last day at Alfresco. I guess it’s natural to have mixed feelings at this point, but when I think of all the amazingly gifted people I have met, the things that we did and the fun we had along the way I feel blessed to have been able to have been part of the journey.

Since I joined in 2005 as the ‘website boy’ I’ve travelled around quite a bit (back when that was a thing), had the pleasure of presenting on technical subjects to many people, many of whom were smarter than me but who gave me their time, attention and encouragement, and worked with some hugely talented but humble engineers, both inside and outside the company.

This was the note I sent round on our internal email group the other day

Nearly 15 years ago (which I remember as it was the week before Christmas and the office was almost empty) I started at a small company called Alfresco, after landing a job re-writing the website. My friends told me I was crazy for taking a job with a company with only 14 employees, but there was something about the three people I’d met during the interview stage (4 if you include JN, who I spoke to on the phone a couple of times, though only because he usually picked it up) that convinced there was something in this open source ECM stuff.

It’s usual when writing these notes to give praise to the technical excellence of your colleagues, and of course that is as true now as it was at the start, but what I think marks Alfresco out more is the humbleness of those people and the time that they have for others, whether in their team, the wider company, our customers and partners or the wider community. I strongly believe that other people notice these things, and the success of the company is in no small part thanks to these qualities.

Although some of the faces have changed over the years, the spirit of the company that wanted to do things differently and disrupt things a little, has not. I am incredibly grateful to all the colleagues over that time who have taught me, given me their trust and encouragement or just shared a coffee or a beer, and from whom I have learnt so much. So thank you.

Alfresco is now part of the Hyland family and I’m sure those people who I will miss so much will do well there. For me some new challenges await next week, more on that some other time.

Tips for Working from Home

One of the consequences of the COVID-19 pandemic is that in the future a lot more people will start to work from home. However more concerning right now is that a large numbers of people who have been used to going into the office the majority or entirety of the time have been asked to change their behaviour quite suddenly, to a model that they’re not that familiar with.

I’m lucky to have worked across a number of teams at Alfresco where working from home has been helpful in many ways over the last few years to me personally, but I’m also aware that there are quite a few pitfalls. So I put together this list to share with colleagues, having definitely exhibited the opposite behaviour of each of these at different times in the past.

  1. Try to keep a normal routine. Although these are not normal times trying to keep to a rough schedule each day will help you manage the predictable and the unpredictable things better.
  2. Your mother was right. Don’t forget to shower, do your hair, brush your teeth and dress properly at the start of each day.
  3. Have a defined and tidy work area where you can work from while you are at home. Move around if you need to, but try to sit up, lying on the sofa or bed will not end well
  4. Not everyone has space for a desk or a good solid table to work at. Use your imagination, e.g. an ironing board can be adjusted to the perfect height as needed and moved around easily.
  5. Take regular breaks, especially for lunch, away from your computer. Do something useful like put some washing on in the background, reducing the technical debt of your laundry pile will make you feel better and will only take a few minutes each day.
  6. Drink plenty of water and eat well, avoid processed food if you can
  7. Have a clear cut-off for work activities, as you would if you were in the office. Remember to schedule time to spend with friends and family (remotely as needed), or join a meetup or other activity remotely after work ends (thanks, Roberto).
  8. Take care of your colleagues. Consider joining remote meetings (we use Zoom) a few minutes early, to have some time for unstructured check-ins and conversations before the agenda kicks in.
  9. Get regular exercise. Although most gyms, health clubs, etc are closed and many organised events such as Parkrun are suspended, it is still recommended in government advice that exercising outside is fine and indeed necessary for maintaining your health and wellbeing
  10. Keep up-to-date with events and news but don’t get hooked on watching rolling TV news or scrolling through social media, it will not make you feel better
  11. Do something small to improve your local world. Say hello to a stranger, ask the person in the shop how they are doing.

If you have conquered all the above, consider helping others in your communities or friendship circles who may be struggling with working remotely or feeling isolated. Many charities are seeking help in this area right now for themselves and their service users, and other groups such as the Marble Arch Partnership who we helped a few weeks ago with some fun Spring gardening activities at the Westminster Society, are actively looking for volunteers to match up to charities.

Media Viewers 2.6 Released

Hot on the heels of the Alfresco Enterprise 4.2 release this week, the Share Extras team have been busy pushing out an updated version of the Media Viewers add-on, which provides support for viewing documents, audio, video and code directly within the web browser in place of the standard Share previewer.
Screen Shot 2013-10-31 at 15.41.29
A key part of the release involved fixing up a few 4.2-specific issues and adding additional support for the new document library views in 4.2 such as the Filmstrip View. But users of any recent version of Alfresco should be able to benefit from some new features – such as a new Present Mode for PowerPoint and ODP files – and developers are also able to customize the toolbar using extensibility modules.
The full list of features is available from the releases page on the GitHub project. But what’s also significant is that this is the first major release we’ve completed for a Share Extras add-on since we completed the migration to GitHub recently. The new process ensures that the release is tagged in the repo, and has binary artifacts available from GitHub and from our new Maven repo (I’m indebted to Gab Columbro for this, who helped to set it up).
I’ll be at Alfresco Summit this year in Barcelona talking about what was involved in the migration, both from a project management and from a technical standpoint in my talk Lessons Learned from Share Extras. You can catch me in Boston too, and at both conferences you’re welcome to book a time to chat about Alfresco Integrations, Share Extras or add-ons in general at the Alfresco Experts bar.

Changes to Transformers configuration in Alfresco 4.2

If like me you have configured some custom transformers against the Alfresco repository in order to convert from one file type to another, you’ll need to be aware of some changes that have been made in the 4.2 codeline currently available in the HEAD branch in SVN and in the latest nightly builds.
The major change is that the mimetype mappings which were previously defined via the Spring bean definitions have now moved to repository properties. This has the benefit that the Spring configuration is much simpler and sys admins can more easily change which transformers are used for specific transforms, as well as the priority assigned to them.
Today I added some default properties to the media-viewers add-on on Share Extras, which you may find useful as a guide to converting over any custom transformer configuration.
Previously in the project, the transformer mimetype mappings were defined on the transformers’ Spring beans via the explicitTransformations property. Here is an extract.

<bean id="transformer.ffmpeg.flv">
    ...
    <property name="explicitTransformations">
        <list>
            <bean class="org.alfresco.repo.content.transform.ExplictTransformationDetails">
                <property name="sourceMimetype"><value>video/mpeg</value></property>
                <property name="targetMimetype"><value>video/x-flv</value></property>
            </bean>
            ...
        </list>
    </property>
    ...
</bean>

This configuration configures this a transformer with the bean ID transformer.ffmpeg.flv, which is capable of converting an MPEG-2 file to Flash Video format (note that the transformation itself is performed by a separate worker bean since Alfresco 4.0, and that whilst not generally recommended, the explicitTransformation list can also be applied to that bean).
In 4.2.d onwards the explicitTransformation property is no longer used, so we must define the following repository properties in addition to the Spring configuration.

# Define a default priority for this transformer
content.transformer.ffmpeg.flv.priority=50
# List the transformations that are supported
content.transformer.ffmpeg.flv.extensions.mpg.flv.supported=true
content.transformer.ffmpeg.flv.extensions.mpg.flv.priority=50
...

It is important to get the format of the properties right, with a prefix of content. followed by the Spring bean ID of the transformer (transformer.ffmpeg.flv in this case), followed by the suffixes above. First we define a numerical priority for this transformer, then each supported transformation must be listed separately, one on each line, with the source and target mimetypes identified by their default file extensions, which can be obtained from the mimetypes web script, e.g. http://localhost:8080/alfresco/service/mimetypes.
As per Alan’s advice on this related JIRA ticket, you can simply add the properties to your installation’s alfresco-global.properties, and they will take effect immediately after a restart, but if your transformer config is packaged up in an add-on then you probably want to ship these properties with it, otherwise the transformer will be automatically configured to transform any mimetype into all others defined in the system (see this issue if you want to understand the consequences of this).
For the media-viewers project I utilised the ability of Alfresco Subsystems to pull in extended configuration properties placed on the classpath under alfresco/extension/subsystems. In this case I used the Transformers subsystem but perhaps thirdParty is also applicable for this, or you could even define your own custom subsystem!
I added the properties in a new file config/alfresco/extension/subsystems/Transformers/default/default/org_sharextras_media-viewers.properties in my project with the above contents (source). The config prefix is part of the standard project source layout and is removed from the classpath of the assets at build time, and the slightly obtuse file name ensures that different add-ons will not clash with each other if they both add additional properties (the file name can be anything, so long as it ends with the .properties extension.
Normally you would remove the explicitTransformations properties from the Spring configuration with these applied, in order to supress the warnings that are now output in the logs, but I made the decision to leave it in, in order to preserve backwards-compatibility with 4.0 and 4.1.
Thanks to the contributors davidyg and touchvignesh who reported these issues with the media-viewers add-on! The updated code is in the master branch on Github or you can grab a JAR file containing the latest code to try it out yourself.

Media Viewers 2.5 Released!

If you’ve been following the recent activity on Share Extras you’ll notice that most of the work for the last few weeks has been going into the Media Viewers project and in particular the ‘PdfJs’ based viewer which it supplies.
If you’re not familiar with the underlying pdf.js project then you should know that it provides a means of direct rendering of PDF content items using HTML5 and JavaScript in the web browser, with no requirement from additional client-side plugins such as Flash.
Combined with the ability of the Alfresco repository to transform just about any standard document into PDF format, we think this provides a compelling reason to try the Media Viewer add-on if you have not done so before.
An initial version of the PdfJs viewer shipped in the Media Viewers 2.0 release for Alfresco 4, and version 2.5 which we’re releasing today builds on that with support for Alfresco 4.2 while also maintaining backwards compatible with the 4.0 and 4.1 Alfresco product lines.
There’s so much in this release that it felt like much more than a v2.1 release and 2.5 seemed much more appropriate. You can read on for more details of these exciting new capabilities, or go straight to the download, installation and configuration instructions to try it out today.

Easy Configuration

The first thing you’ll notice when enabling the add-on using Share’s Module Deployment console is that additional modules have been added, which provide the configuration needed to bind the viewer into the document details page.
Unless you want a specific custom configuration, you can just enable the new PdfJs Configuration module (in addition to the existing PdfJs Viewer module), click Apply Changes and you should see PDF documents will now use the new viewer. You no longer need to edit your web-preview.get.config.xml file although if you’ve made changes there they will continue to be respected.

Persistent View Settings

Can’t see the text clearly? You can use the zoom controls in the viewer to zoom in, our out if you want to see more. Or pick a preset from the drop-down and the zoom will be auto-calculated.
The next time you come back to the document, these settings – plus the page number you were on – will be remembered.

Powerful Search

Use the Search button in the toolbar or Ctrl+F (Cmd+F on MacOS) to search through the document contents for a particular item of text. You can easily step through the matches one by one, or highlight all matches found.

When you’ve found what you’re after, you can copy the relevant text to the clipboard in order to include it somewhere else, for example in an e-mail.
The feature I like the most will make you wonder how you lived without it before, if you’ve ever searched for a document in Alfresco and then struggled to find the reference to that term in the document itself.
Now, the viewer detects that you have clicked through from the search page, and automatically searches for and highlights the first match of that term. Just hit Enter to continue through any further matches, or Escape to close the search dialog.

Link to Document

The Link button in the toolbar generates a link to the document, or even to a specific page in the document, that you can send to co-workers. If you want them to review Slide 24 in your presentation then simply send them straight there.

Improved Sidebar

You can click the button on the left of the toolbar to toggle the side bar on and off. The side bar shows a thumbnail view of all pages in the document by default and can also show an outline of the document structure if available in the file.

Presentation Mode

At DevCon last November Jared neatly showed how you can use the the new Google Docs integration to deliver a presentation directly from your web browser using Google Drive’s presentation mode, but with the PdfJs viewer you can now do the same thing directly from the Document Details page.
Just click Ctrl+Enter (or Cmd+Enter on MacOS) to go full-screen, then use the left and right arrow keys to move between your slides (the arrow keys will also work in the normal Document Details view).

Document Viewer Dashlet

Just like Site Admins can use the Wiki dashlet to add a selected page to a site dashboard, the Document View dashlet supplied with the add-on allows you to display any chosen document on the dashboard.
The dashlet works well with the PdfJs viewer, but will also work with the others supplied by the add-on or the base viewers supplied with Share (yes, that includes the Flash document viewer, if you really want).

Password-protected PDFs

Viewing password-protected PDFs is no longer a problem with the PdfJs viewer. You will be promoted for the password required to open the file and once supplied the viewer will work as normal.

Lots More

Of course there are many other improvements that you can’t see directly, but that you will benefit from. Peter has been working tirelessly to keep the version of the pdf.js library up-to-date, ensuring that we stay up to date with the improvements in performance and compatibility that the latest versions now provide. We have also improved the performance of page rendering within the dashlet code itself, with improved lazy rendering of all page and thumbnail content.
And of course PdfJs is not the only viewer in the add-on. The Flash-based audio and video players are still supplied, the Embed viewer offers a compelling Flash-free alternative for IE users not on IE 10 who have the Adobe Reader or another PDF plugin installed and the Prettify viewer is great at syntax highlighting any code stored in Alfresco.

Feedback

Like all Share Extras add-ons, we welcome constructive feedback to help us to deliver the next version of Media Viewers. Please use the Issues section on the project to report specific technical issues or ideas for enhancements, or general feedback can be left as comments below.

Media Viewers and Quick Share

Peter helpfully put together a summary of a couple of the many different content viewers that are now provided by the Media Viewers project. His blog post is well worth checking out if you’re not familiar with the Embed and PdfJs viewers, or if you have content types that you have problems previewing in Share today.
He also pointed out something that may be obvious to some of you, but it had not occurred to me! When you add a new plugin to Alfresco’s web preview component – as this add-on does – then that is also available on the Quick Share page.

If you’re not familiar with Quick Share it is a great new feature originally in Cloud and now in Community 4.2, providing public sharing of documents via a short URL, which can be easily used by clicking the Share action directly above the document preview.
The result is pretty powerful, since using an iFrame you can easily add those embedded documents to an intranet page or public web page – or just link to the items direct as Peter has done in his post. In fact Sergio Buitrago and I worked on this implementing this very thing as a WordPress plugin at the Berlin DevCon Hackathon last month!

Latest Changes in PdfJs Viewer

It’s worth mentioning that you can try out the features Peter mentions by grabbing the project’s latest source from trunk. In particular, here are two new features that are hot off the press in the PdfJs viewer:

  • Perform a search in Share and click through to a PDF file or office document. You should see that the search function is automatically invoked for the term you searched for in the previous page, and highlights the first match.
  • If you are using the latest available Firefox or Chrome browsers, you can enter full-screen mode by pressing Ctrl+F on the keyboard. Now you can deliver PowerPoint presentations directly from Share itself!

We are still in the process of finalising the 2.1 release of the Media Viewers add-on, so if you have feedback please file an issue on the Share Extras project site.

DevCon Berlin rocked, now to San Jose

So with last week’s DevCon event in Berlin over and the second event in San Jose about to kick off, I wanted to share a few of my highlights so far, in addition to what Jeff already posted.
Tor Brandenburg
Last week kicked off with a full-day hackathon building on top of Alfresco, facilitated by Nathan McMinn, which I would recommend to anyone who has worked with Alfresco before and is interested in expanding  their horizons. This was about people coming together to work collectively on building something in a day, and the format worked fantastically well. I believe Nathan will be posting soon on what was produced in the session.
As always John and John kicked off the main sessions with the high-level view of Alfresco, seamlessly mixing open source content management with tales from the wider IT industry and a satirical take on current global politics. If you’re interested in any of those things, it’s a must see.
I didn’t get to see as many technical sessions as I have done in previous years, but the quality of those I did see really stood out. In particular:

  • The public API live coding (part 1, part 2) session by Peter, Gethin and Steve was a great opportunity to get to grips with Alfresco Cloud’s new public API, and like the hackathon it felt great to have some working code at the end, much aided by the sample project provided on the USB sticks.
  • Expanding on the idea of developing your own projects, Gab Columbro’s talk on the long-awaited and brand-new Maven SDK was a highlight as much for the content as for Gab’s style, although you’ll want to do some background reading on Maven and how it differs from more traditional build tools before you use it for real.
  • On the second day I attended Dave and Erik’s Share Customizations Live session where they demonstrated, through the use of site presets and extensibility modules, some concrete examples which showed them taking a vanilla Share and hacking away until it was barely recognisable. What was interesting was how the mechanisms for doing this have improved over the last year, and the point that often it is just as useful to remove non-required OOTB functions as it is to add new ones, which the framework makes easy.
  • Jared’s talk on our own Integrations team and what we’ve been up to over the last year (or six months in my case), and Nathan’s overview of PDF Toolkit and the latest new features, based on the work he’s done recently building on Jared’s earlier work. If you’re interested in integrating Share with external systems and working with PDF content you’ll find both sessions really useful.

Overall what stood out this year for me was the diversity of sessions available, not only in terms of topics but in their formats as well. There were less of the traditional-style PowerPoint-only type of sessions and more richer interactive sessions.
I experimented with a local Git repo in my own Developing Great Dashlets talk, switching between eight different branches of my example project to show progressively adding more features to an at-first-basic dashlet. It was great to see others experimenting in even more ways and adding more diversity to the two days.
If you’re attending the event in San Jose you’re I’ll be presenting the same dashlets “Zero to Hero” talk on Day 1 and Day 2, plus a topic on pimping the Document Details screen with your own document viewers and a lightning talk on the fantastic Leaflet. Do join if you can!

CMIS support in LibreOffice Experimental Features

Since I upgraded the LibreOffice installation on my Macbook to version 3.6, I’ve been playing around with the CMIS integration built into this version. This is currently an experimental LibreOffice feature, which means you should not use this against a production server.
The integration allows LibreOffice to connect to a remote Alfresco server in order to open and save documents. This is a feature Microsoft Office has had for a long time, although limited to SharePoint-compatible servers (including Alfresco, via our SharePoint protocol support!). Now you can do the same thing with LibreOffice, via the magic of CMIS.
The first thing to do is to enable LibreOffice’s experimental features within the Preferences dialogue.

After you’ve confirmed that change, you can open a file stored in Alfresco using the standard Open menu. When the file browser loads, you should notice a small button next to the location drop-down menu labelled with an ellipsis (…).

Clicking that button allows you to add a server. LibreOffice supports a range of server types, including the CMIS AtomPub service provided by Alfresco.
First you must enter a name for the server – I entered ‘Alfresco’ – and select the server type. If you do not see CMIS (Atom Binding) in the list then check to ensure that you have LibreOffice 3.6+ and that you have enabled Experimental Features.

The binding URL for Alfresco 4.2 will be something like http://localhost:8080/alfresco/cmisatom if you are running a local instance. I found that if I used the legacy CMIS URL below /alfresco/service (or the short form /alfresco/s) then document saves did not work, but the newer URL worked great.
Next is the slightly tricky part, entering the CMIS repository ID. Your Alfresco instance will only expose one repository, but other CMIS providers provide others, and so you need to enter this.
Hitting the repository binding URL directly will give you the ID, but unfortunately the non-standard document MIME type returned means it does not open directly in a web browser. You could save the response to disk and then use a text editor to view its contents, but I found it easier to use curl at the command line, together with less.

curl -u admin:admin http://localhost:8080/alfresco/cmisatom | less

In the response, do a search for the string repositoryId and within that element you should see a GUID value which you can copy and paste into the dialogue in LibreOffice.
The last item you need to enter is the username that will be used to access Alfresco (you will enter the password later).

You should now have the full set of information needed to add the server. Click OK, and it should be added to the side panel on the left of the Open dialogue.
You can navigate through the folders below the repository’s Company Home space, and open any compatible document. I used the Word documents located under Sites > swsdp > documentLibrary > Meeting Notes, which opened perfectly.

You can make any modifications, hit Save and the content will be automatically saved back into Alfresco.

I also tried creating a new document from the New menu, and was able to save the document back to a folder Alfresco via the Save As dialogue. I found I needed to set the correct MIME type for new documents back in Alfresco Share to get previews to work, but this could easily be done using a rule.
All in all not bad for an experimental feature, and it will be interesting to see if this makes it into LibreOffice 3.7 for real.

New Notice Dashlet and Improvements for Developers

Following hot on the heels of the 4.2.a release from last week, it’s great to see 4.2.b going out this week with another bunch of improvements before DevCon. I’ve been able to help get a few more changes into the this release, which provide a new dashlet and several improvements for developers.

Notice Dashlet

This dashlet may already be familiar to some of you who have used the add-ons available from Share Extras.
The Notice Dashlet allows site managers to add a custom notice that will be displayed to all site members, and allows this to be done directly from the dashlet itself. Now you no longer need to create a wiki page just to display some basic text on the dashboard!

New Bubbling event for dashlet resize notifications

If you’ve developed any complex dashlets to render maps or other graphics, you’ll appreciate that it’s important to know the vertical height of the dashlet when you render your content. That is easy to get via the Dom or using YUI2’s YAHOO.util.Dom.getRegion() function, but what if the user resizes the dashlet?
Now the resizer module can notify your listeners via the new Bubbling event dashletResizeEnd. This is fired when the resizing has been completed and passes a number of parameters in the event arguments, including the new height of the dashlet, the dashlet element and component IDs and the Dom element representing the dashlet. To subscribe to the event, simply define a new custom function in your dashlet class prototype and bind it to the event in the dashlet class constructor, e.g.

YAHOO.Bubbling.on("dashletResizeEnd", this.onDashletResize, this);

In your custom function you can then take any further action which is necessary, e.g. informing a map instance that the element bounds have changed.

More options for Data List actions

The ability to add custom UI actions to Share’s Document Library is well documented and the add-ons site has a number of extensions which utilize this capability. But did you know the same thing can be done for data list items?
Until now the number of actions that can be displayed in the UI has been effectively capped at three. But now you can easily add new actions of your own there too. Thanks to the work done by Dave Draper these definitions can easily be inserted into the application by using an extensibility module to customize the datagrid.get and actions-common.get components.

As an example, the following code could be used to add the Sample Datalist Action provided by Share Extras to your datalist items, as part of an extensibility module.

if (model.widgets)
{
   for (var i = 0; i < model.widgets.length; i++)
   {
      var widget = model.widgets[i];
      if (widget.id == "DataGrid")
      {
         // These two lines only needed if you want to show the action in the 'actions' cell,
         // otherwise a 'More actions' menu will be created to display it.
         //widget.options.splitActionsAt = 4;
         //widget.options.actionsColumnWidth = 105; // splitActionsAt * 25 + 5
         // Add the action definition - this will be action-specific
         model.actionSet.push({
            id: "onActionSample", // Change to match your handler function name
            type: "action-link",
            permission: "",
            href: "",
            label: "actions.datalist.mycustom" // Change to match your custom label in datagrid.get.properties
         });
      }
   }
}

If you have attempted to customize the existing Edit and Create data list actions with your own custom form configuration, then you may also appreciate the ability to increase the width of the modal dialogs used here, which previously were fixed-width.

Better handling of missing custom previewers

This will mainly be of interest to developers and administrators working with custom viewers in the web preview component, such as the pdf.js viewer in Share Extras’s Media Viewers add-on, and is a topic which I’ll be talking about in San Jose next month.
Previously, if the files implementing the viewer were unavailable for some reason then an error would be thrown in the client-side component. With this change the component now logs that the viewer class could not be found, and this will also be printed on the screen if no other viewers can be found.

Creating self-signed SSL certificates for Solr

Since the default SSL certificates that ship with Alfresco’s Solr integration expired the other week I’ve been having to fix up my local development installs that I’d previously configured with Solr.
The instructions on the wiki are pretty comprehensive, and together with the text file provided in the Solr integration package provide all the info you need to understand the process of creating your own keys and certificates for local testing.
After I stepped through the complete procedure documented there, with some slight modifications to avoid the interactive prompting, I found I had a set of commands which I could use in order to repeatedly re-generate a set of keys inside each installation directory on my system.
The first section in the following listing could be placed inside your .bash_profile file, and this is recommended to ensure that the password values you choose to use are not captured in your command history or in your terminal. The commands after that should be used repeatedly against each Alfresco installation you wish to generate keys and certificates for.

# The subject name of the key used to sign the certificates
REPO_SUBJECT_NAME="/C=GB/ST=UK/L=Maidenhead/O=Alfresco Software Ltd./OU=Unknown/CN=Alfresco Repository"
# The repository server certificate subject name, as specified in tomcat/conf/tomcat-users.xml with roles="repository"
REPO_CERT_DNAME="CN=Alfresco Repository, OU=Unknown, O=Alfresco Software Ltd., L=Maidenhead, ST=UK, C=GB"
# The SOLR client certificate subject name, as specified in tomcat/conf/tomcat-users.xml with roles="repoclient"
SOLR_CLIENT_CERT_DNAME="CN=Alfresco Repository Client, OU=Unknown, O=Alfresco Software Ltd., L=Maidenhead, ST=UK, C=GB"
# The number of days before the certificate expires
CERTIFICATE_VALIDITY=36525
# Keystore password
KEYSTORE_PASSWORD=custompassword
BROWSER_KEYSTORE_PASSWORD=alfresco
openssl genrsa -des3 -passout pass:$KEYSTORE_PASSWORD -out ca.key 1024
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt -passin pass:$KEYSTORE_PASSWORD -subj "$REPO_SUBJECT_NAME" -passout pass:$KEYSTORE_PASSWORD
# Generate Alfresco Repository SSL keystores
keytool -genkey -alias 'ssl.repo' -keyalg RSA -keystore ssl.keystore -storetype JCEKS -dname "$REPO_CERT_DNAME" -storepass "$KEYSTORE_PASSWORD" -keypass "$KEYSTORE_PASSWORD"
keytool -keystore ssl.keystore -alias 'ssl.repo' -certreq -file repo.csr -storetype JCEKS -storepass "$KEYSTORE_PASSWORD"
openssl x509 -CA ca.crt -CAkey ca.key -CAcreateserial -req -in repo.csr -out repo.crt -days "$CERTIFICATE_VALIDITY" -passin pass:$KEYSTORE_PASSWORD
keytool -import -alias 'alfresco.ca' -file ca.crt -keystore ssl.keystore -storetype JCEKS -storepass $KEYSTORE_PASSWORD -noprompt
keytool -import -alias 'ssl.repo' -file repo.crt -keystore ssl.keystore -storetype JCEKS -storepass $KEYSTORE_PASSWORD -noprompt
keytool -importkeystore -srckeystore ssl.keystore -srcstorepass $KEYSTORE_PASSWORD -srcstoretype JCEKS -srcalias 'ssl.repo' -srckeypass $KEYSTORE_PASSWORD -destkeystore browser.p12 -deststoretype pkcs12 -deststorepass $BROWSER_KEYSTORE_PASSWORD -destalias repo -destkeypass $BROWSER_KEYSTORE_PASSWORD
keytool -import -alias alfresco.ca -file ca.crt -keystore ssl.truststore -storetype JCEKS -storepass $KEYSTORE_PASSWORD -noprompt
# Generate Alfresco Solr SSL keystores
keytool -genkey -alias 'ssl.repo.client' -keyalg RSA -keystore ssl.repo.client.keystore -storetype JCEKS -storepass $KEYSTORE_PASSWORD -keypass "$KEYSTORE_PASSWORD" -dname "$SOLR_CLIENT_CERT_DNAME"
keytool -keystore ssl.repo.client.keystore -alias 'ssl.repo.client' -certreq -file ssl.repo.client.csr -storetype JCEKS -storepass $KEYSTORE_PASSWORD
openssl x509 -CA ca.crt -CAkey ca.key -CAcreateserial -req -in ssl.repo.client.csr -out ssl.repo.client.crt -days "$CERTIFICATE_VALIDITY" -passin pass:$KEYSTORE_PASSWORD
keytool -import -alias 'alfresco.ca' -file ca.crt -keystore ssl.repo.client.keystore -storetype JCEKS -storepass $KEYSTORE_PASSWORD -noprompt
keytool -import -alias 'ssl.repo.client' -file ssl.repo.client.crt -keystore ssl.repo.client.keystore -storetype JCEKS -storepass $KEYSTORE_PASSWORD -noprompt
keytool -import -alias 'alfresco.ca' -file ca.crt -keystore ssl.repo.client.truststore -storetype JCEKS -storepass $KEYSTORE_PASSWORD -noprompt
# Copy files
cp ssl.keystore ssl.truststore browser.p12 data/keystore/
cp ssl.repo.client.keystore ssl.repo.client.truststore solr/workspace-SpacesStore/conf
cp ssl.repo.client.keystore ssl.repo.client.truststore solr/archive-SpacesStore/conf
# Remove temporary files
rm repo.csr ca.key ca.crt repo.crt ssl.keystore browser.p12 ssl.truststore ssl.repo.client.csr ssl.repo.client.crt ssl.repo.client.keystore ssl.repo.client.truststore

Note that this will not update the Alfresco and Solr configuration with the password you choose for the keystores – you must do this separately in your alfresco-global.properties and in the properties file associated with each Solr core, as detailed in the Solr installation guide.
Lastly, this procedure should not be used in any public-facing or production instances, it is intended to be used in development environments only.