Thursday, May 25, 2017

Installing the WeBWorK opaque server and the Moodle opaque client

Installing the WeBWorK opaque server and the Moodle opaque client


The Opaque question type and the Moodle Opaque client were created by Tim Hunt to allow webservices to power questions used in the Moodle quizzes. They were specifically designed to work with the OpenMark question engine at the Open University in England with the expectation that they could interoperate with other question engines as well. 
The WeBWorK Opaque server described in this document accepts requests from the Moodle Opaque client and returns a rendered PG question. 
The combination of the Moodle Opaque client and the WeBWorK Opaque server allows any WeBWorK question to be included in a Moodle quiz giving Moodle quizzes access to the entire range of mathematics questions commonly used in WeBWorK homework installations, in particular all of the questions in the OpenProblemLibrary. The WeBWorK/Opaque question type behaves much like STACK questions (created by Chris Sangwin) and supplements the mathematics questions available from STACK (System for Teaching and Assessment using a Computer Algebra Kernel).
This is a first attempt to interface WeBWorK (or to my knowledge any question engine besides OpenMark) with the Opaque client. Suggestions for improvements particularly from experienced Moodle users familiar with question “behaviours” and how to configure them to best advantage are welcome.
The main steps are as follows:
  1. Install the opaque question type client in Moodle
  2. Configure the Moodle question engine (and test)
  3. Create a Moodle quiz with opaque questions (and test)

The steps above do not require you to set up your own opaque server. You can use the publically available opaque servers listed to test that the Opaque client and Moodle quiz have been set up correctly. 
If you already have a WeBWorK installation then adding the WeBWorK Opaque server is straight forward. “Install the WeBWorK Opaque Server”. 
To see the tools available for duplicating an existing WeBWorK course asa course using Moodle quizzes read the section “How to transfer a WeBWorK course with homework sets to a Moodle course with quizzes”.

1. Install the opaque question type client in Moodle
Tim Hunt presents an overall description of the Opaque question type client and how to install it at We repeat specific instructions here:
  • Requirements
    1. Moodle 2.5 or later
    2. These notes were and pictures were created using Moodle 3.0
    3. We are assuming that Moodle is installed at /opt/htdocs/moodle.
    4. (Another common location for moodle is /var/www/html/moodle in which case you will need to translate these commands)
  • Steps, using git to obtain software
    You may need to prefix some of these operations with
    sudo if system level privileges are required for these directories.
    1. cd /opt/htdocs/moodle/question/type
    2. git clone opaque
      • This will create a directory opaque in this directory
    3. cd /opt/htdocs/moodle/question/behaviour
    4. git clone opaque
  • You need to make one small change in the “out of the box” code:
    1. Edit the file /opt/htdocs/moodle/question/type/opaque/connection.php
      • comment out line 174. It should read
        //$headers[] = 'SOAPAction: none'; //Seemingly, this is necessary.
      • For the WeBWorK Opaque servers this line will cause errors if it is not commented out.
  • For future reference here are instructions for updating the opaque client software
    1. cd /opt/htdocs/moodle/question/behaviour/opaque
    2. git branch # you should see the response “master” since you are on that branch
    3. git pull or git pull origin # these will download the latest software changes.
  • If you you would like to test out the clients before installing the server you can skip to the section “Configuring the Moodle question engine”. When configuring the question engine point to servers at URLs or for test purposes and use the course daemon_course as part of the question bank URL.
  • Tim Hunt presents a more technical description of the Opaque question type at

2. Configure the Moodle question engine
  • The Opaque question type and the opaque question behavior modules need to be installed in your Moodle course. You will need to have admin privileges in Moodle to configure the Opaque question engine.
  • Set Moodle preferences at:
    site administration -> plugins -> question types-> Opaque
  • Create a new question engine. The required entries are:
    • Engine name:
      any string: I often use a course name
    • Question engine URLs:
    • Question bank URLs:
    • If you have not yet set up your own Opaque server or wish to
      trouble shoot the Moodle configuration of the question engine using a stable Opaque server you can use
      • and
      • or and
      • These sites are usually up and running but that can’t be completely guaranteed.
  • Save changes!!
  • The configuration page looks like this:

  • After saving you see the list of question engines: in this case spring09mth165 and spring16mth162. The first engine is being used by 272 questions, but a newly created engine will not be used by any questions and will have an X next to it which indicates that it can be safely deleted. Clicking on the “spy glass” (looks like a Q) will allow you to test the engine. Clicking on the wheel will allow you to re-edit the engine entries.

Manage question engines

  • The screen shot below indicates a successful connection for the question engine.

Engine test success

  • Assigning the engine a name related to a course name (e.g. MTH162) and then assigning all of the moodle questions for that course to the engine of the same name is not required but can be convenient. If you change the URLs for the “MTH162” engine all of the questions for the course will be rendered on the new server.
  • The course name (daemon_course) is often the course on the opaque server that will be used to access library problems and any “local” problems which have not been shared with the library, however any WeBWorK course can be used. For production use it’s safest to create a separate course with no students and few professors to use as the base WeBWorK course for a Moodle quiz engine.
  • To add daemon_course to a WeBWorK installation you will need administrative privileges. Login at, select the “add course” tab and fill out the form to create a new course called daemon_course. The questions available to daemon_course will be available to all Moodle quizzes through the connecting Moodle quiz engine.

What else can go wrong?
  • Did you remember to modify the file /opt/htdocs/moodle/question/type/opaque/connection.php? If you didn’t you will get a SOAP error.
  • In one case it was necessary to make the following modification at line 69 in the connection.php file. For most installations this was not necessary. Replace
    $this->soapclient=new $class($url.'?wsdl',array(...));
  • by
  • $this->soapclient=new $class($url,array(...));

    Usually the extra ‘?wsdl’ segment appended to the url is ignored but apparently not always.
  • If you can successfully connect to one of the rochester servers with the question engine but cannot connect to your own new server here are a couple of trouble shooting ideas.
    • If you type https://<your_ww_server_url>/opaqueserver_wsdl you should get back a page of XML code describing the server. If you don’t then perhaps there is an error in the site url or in the configuration line in the webwork.apache-config file or in the opaqueserver.apache-config file.
    • Did you restart the apache server after making modifications? including modifications to the config files?
    • View the apache server error_log (you’ll have to find this yourself – it is in different places on different systems) and see if there are error messages. You can also view the apache access_log to see if the request is reaching the server.
  • Did you spell “behaviour” properly? The Moodle quiz module was made in England. :-)

3. Create a Moodle quiz with opaque questions

In a Moodle course
  • Click the “turn editing on” block
  • Click “Add an activity or resource”
    • Choose “Quiz” radio button
    • Click “add” button
  • Fill in form to create the quiz
    • Name: e.g. “test 2”
    • description
    • timing – this allows you to specify open and closing dates. Leaving them blanks leaves the quiz always open.
    • Question behaviour: set to interactive with multiple tries
    • Click “Save and return to course”
  • Click “test 2” to reopen the quiz.
    • Click edit quiz
    • Click “add” pop down menu on the right
    • Choose “new question” and then choose the “opaque” type and save.
    • Fill in form
      • Name: intervals
      • Question Engine: devel3_ww_opaque_server
        • this will be the name of one of the question engines you defined.
      • Question id:
        • the original path was Library/Rochester/setAlgebra01RealNumbers/
        • slashes are replaced by two underbars: __
        • hyphens - are replace by three underbars: ___
        • The initial Library is changed to library
      • Question version: 1.0
    • Click “Save changes”

  • Add another question to “test 2”
    • To add another question first “edit test 2”
    • Then choose “Edit quiz” under the “Quiz Administration” menu in the left margin. (See below. This is NOT intuitive, but you get used to it.)

    • Now choose “add” where you want to enter the next problem

      • Name: derivative
      • Question Engine: devel3_ww_opaque_server
      • Question id:
        • the original path was Library/Rochester/setDerivatives1/
      • Question version: 1.0
      • Click “Save changes”
        engineConfig: 2016–04–05_18–21–10.jpeg “Edit engine configuration”

  • You have created two new questions and put them in a quiz. You can now return to the homepage of that course and try the quiz.


This is a good place to pause and check that you understand how the Moodle quiz and questions work.
If you plan to set up a local Opaque server this is a good opportunity. If you already have a working WeBWorK installation then installing the WeBWorK opaque server is straightforward. 
If you don’t want to set up an Opaque server at this time skip to the section “How to transfer a WeBWorK course with homework sets to a Moodle course with quizzes”. While you can use the sites at hosted2 and devel3 for testing they should not be relied on for production work hosting actual classes. 

Install the WeBWorK opaque server
  1. Requirements
    • This version of opaque server should work with release 2.10 and later of WeBWorK. It has been extensively tested with release 2.11 and release 2.12
    • You will need to have the webwork2 and pg software already installed. This software can be obtained at You will also need the OpenProblemLibrary of questions installed.
    • The standard directory structure for webwork is
    •     /opt/webwork/webwork2
    •     /opt/webwork/pg
    •     /opt/webwork/libraries/OpenProblemLibrary
    •     /opt/webwork/libraries/Contrib

    • We’ll add the opaque software to the directory ww_opaque_server under /opt/webwork and along side webwork2 and pg.

You may need to prefix some of these operations with sudo if system level privileges are required for these directories.
  1. Obtain the software for the opaque server using git
    • cd /opt/webwork/
    • Clone the repository to /opt/webwork/ww_opaque_server
      • git clone ww_opaque_server
    • cd ww_opaque_server
    • git fetch # update data from origin repository in the cloud
    • You may need to prefix some of these operations with sudo if system level privileges are required for these directories.
  2. Configure ww_opaque_server
    • cd ww_opaque_server/conf
      • (that is /opt/webwork/ww_opaque_server/conf)
    • cp opaqueserver.apache-config.dist opaqueserver.apache-config
      • this makes a local copy of the configuration file
    • Edit addresses in opaqueserver.apache-config
      • For example, the value of my $hostname = ''; should be replaced with the url of your server '<your_ww_server_url>' instead of ''
    • There are two debugging flags that can be turned on to provide extra information while setting up the connection between the Opaque client and the Opaque server.
  3.         $OpaqueServer::Constants::displayDebuggingData = 1;
  4.         $OpaqueServer::Constants::logDebuggingData =1;

  5. These should be turned off (set to 0) for production use with students.
    * The other constants can remain unchanged if the directory structure is as described above.
  6. Add configuration line to webwork2 and restart
    • Add the following line to the end of the file webwork.apache2-config or webwork.apache2.4-config in the directory /opt/webwork/webwork2/conf. Which file you use depends on whether you are using the apache2.4 server or an earlier version.
    • Include /opt/webwork/ww_opaque_server/conf/opaqueserver.apache-config
    • This commands adds the opaqueserver configuration file onto the configuration file to the webwork installation.
  7. Restart your apache server!!!!!
  8. Test. A minimal test consists of typing https://<your_ww_server_url>/opaqueserver_wsdl into your browser. You should receive back a long page of XML. For comparison you can use the url

What could possibly go wrong?
  • Did you remember to restart your apache server? :-)
  • If there is a CPAN error messge you may need to add CPAN file Memory/
    • This requires system wide privileges in most cases
    • The command for installing a CPAN module is
    • cpan Memory::Usage
    • It’s possible that the error message may report other CPAN modules as missing as well. Running /opt/webwork/webwork2/bin/ performs an approximate check to see whether the appropriate CPAN modules have been installed.

That’s it for the opaque server. Now we’ll test the connection
by creating an Opaque question engine and uploading some problems.

How to transfer a WeBWorK course with homework sets to a Moodle course with quizzes.

This section explains how to transfer myCourse from a WeBWorK homework course to an equivalent Moodle course using quizzes. 
Before you begin this section you may want to delete the quizzes and and questions and the question engines that you created while testing the Moodle client (and Moodle server) in the sections above.
At least make sure that the category names and question engine names that you used in the initial testing are different from the names that you will use in creating the new Moodle course. (The section below on “what can go wrong” explains why.)
Let’s begin: 
  • You will need to use git to clone the tools from the github repository setdef2moodlequiz hosted at Place the tools in a directory setdef2moodlequiz where ever you like on your desktop computer.
  • Using the Homework editor Export all of the active sets from myCourse. This saves the current configuration of each set to a set definition file: e.g. SetOne.def, SetTwo.def etc.

1. Obtain the set definition files from WeBWorK
  • Download these set definition files to a folder on your desktop using the File Manager link in the left margin of the WeBWorK homepage.
    • You can choose all of the appropriate .def files using “command-click” and then click the “Archive” button. This will collect all of the choosen files into an archive (with .tgz extension – possibly myCourse.tgz) which you can then download.
    • Place the downloaded file in a directory labeled myCourse and double click to unpack the archive. Or use tar -zxv myCourse.tgz on the commnand line.
    • You can now delete the .tgz file.

2. Convert the set definition files to a moodleQuestions XML file
  • We’ll let path_to_def_files be the full path to the directory filled with set definition files which you have created above and let path_to_setdef2moodlequiz be the full path to your directory of downloaded tools.
  • In addition we will use the following parameters
    • --engine=newEngineName
    • --category=newCourse the top category for all of these questions
    • --server=
    • --servercourse=daemon_course
    • --qnum=1000 # start numbering added questions at 1000=2``
  • For example on the command line type this:

$ ./ \
> --engine=spring09mth165 \
> --category=spring09mth165quiz \
> --server= \
> --servercourse=daemon_course \
> --qnum=1000 \
> spring09mth165quiz  > spring09mth165_moodle_quiz.xml

The space-backslash-return sequence used at the end of each line make the explanation more readable however the whole command can also be entered on a single line:
$ ./ --engine=spring09mth165 --category=spring09mth165quiz --server= --servercourse=daemon_course --qnum=1000  spring09mth165quiz  > spring09mth165_moodle_quiz.xml

The result will be something like: 

Reading set definition files from directory 'spring09mth165quiz'

Created category 'spring09mth165quiz' for engine 'spring09mth165' which will render questions through the course 'daemon_course' at the server ''

The full baseURL is ''.xmlQuestions: '1000' to '1272'

* Many of these options are set by default taking their value from the name of the directory containing the set definition files.

The command

$ ./ spring09mth165quiz  > spring09mth165_moodle_quiz.xml

Results in: Reading set definition files from directory 'spring09mth165quiz'

Created category 'spring09mth165quiz' for engine 'spring09mth165quiz' which will render questions through the course 'daemon_course' at the server ''
The full baseURL is ''.
    xmlQuestions: '1000' to '1272'

  • Or use the --course=... to set the course, category and engineName independently of the name of the directory containing the set definition files.
The command: 

$ ./ --course=myNewCourse spring09mth165quiz  > spring09mth165_moodle_quiz.xml

Results in: Reading set definition files from directory 'spring09mth165quiz'

Created category 'myNewCourse' for engine 'myNewCourse' which will render questions through the course 'daemon_course' at the server ''
The full baseURL is ''.
    xmlQuestions: '1000' to '1272'

  • To use your own server instead of hosted2 set server=https://<> and the servercourse to <myDaemonCourse>.

Sanity tests:
  • Notice that unless the course option is given the directory name is used for the course and then passed on to “category” and “engine” unless those options are explicitly set. The server defaults to the hosted2 url and and the servercourse defaulted to daemon_course. The baseURL returned by the script is the address of a standard webwork course.
  • Paste the baseURL into a browser and make sure that it connects you to a WeBWorK course. If it doesn’t then there is probably an error in specifying the server URL or the course name or both.
  • If you paste into a browser you should get a page of XML indicating that the opaqueserver is working at that site.
  • The .xml file created should have contents similar to this:

<!-- question: 1002  -->
  <question type="opaque">
    <questiontext format="moodle_auto_format">
    <generalfeedback format="moodle_auto_format">

3. Create a course in Moodle
  • Now to create a copy of myCourse in Moodle. You need admin privileges on the Moodle site. Both for course creation and for editing any mistakes that are made in defining the question categories and question engines.
    • Choose “site administration -> courses-> Manage courses and categories”
    • Choose link “create a new course” and fill out form
      • Choosing “Class format” to be “weekly” with 15 weeks is reaonsable.
    • Navigate to join the course
      • You can change choices, such as the name and format, by choosing
      • “Course administration -> Edit settings” from the left margin.

4. Check for existing questionEngines
  • You need admin privileges for the site.
  • Click “Site administration->plugins->question types->Opaque” (lower left margin) and look at the engines that have been created.
  • Make sure that you are using a new name for your category and engine names. (See “what can go wrong” section below).

5. Import questions into the question bank
  • Click on “Course administration -> question bank->import”
  • Click radio button “Moodle XML”
  • Click on “General” and choose the top level category for your questions. The default “myCourse” is usually fine.
  • Now import questions by clicking on “choose file”.
    You will need to navigate to find the
    newCourse_quiz_questions.xml file – which you will upload to a directory controlled by moodle – you can call the uploaded file whatever you like – say newCourse-quiz.xml
  • Click the button “import”. You should see “parsing questions from import file” and “importing xxx questions from file”.
  • The questions uploaded will be blank – but they will be numbered.
  • Scroll down and click “continue”
  • Under “select a category” you will see a menu
    • myCourse
      • set1 (xx)
      • set2 (xx) etc.
  • Selecting set1 you should see a list of problems with titles of the form
    • set1Prob01
    • set1Prob02
    • etc. These are all of the problems used in the set1 homework set.
  • Click on the “spy glass” next to the question to determine whether the question can be rendered with the engine you designated on the site you designated with the --server option.

6. Create quiz
We’ll create one quiz for each homework set and place it in the appropriate week in the course. Setting up 14 or 15 quizzes is unavoidably a tedious process. Fortunately the quizzes can be saved, exported and reused in other courses.
  • On the Moodle homepage click the button “turn editing on” in the upper right hand corner.
  • Create the first quiz in the second week of the course by clicking “add an activity or resource” in the second week slot and then clicking the quiz radio button followed by clicking “Add” at the bottom of the page.
    • Give the quiz a name “Homework1” and set the “Question behaviour” to “immediate feedback”. Other settings (such as the due dates which are set under “Time”) can be handled later.
    • You can save a little time by duplicating the quiz you have just created, moving it down one slot into the next week and changing the name to “Homework2”.
    • Continue until all of the quizzes are in place, one for each week.
  • Next we will fill each of the quizzes with questions from the corresponding homework sets imported from WeBWorK.
    • Click on the first quiz. You will see “no questions have been added” and a button “Edit quiz”. Click on that button, or alternatively (and non-intuitively) click on the “edit quiz” gear in the lower part of the “quiz administration” menu in the left margin.
    • To add questions click on the “add” menu on the right and choose “from question bank”
    • You will see the questions you have imported. Inspect the “select category” menu at the top and you will find that a category has been created for each homework set which you imported.
    • If you choose the category “set1” (or similar name) you will see all of the questions in that set. You can select them all simultaneously by using the checkbox labeled “T” and add them to the current quiz.
    • Of course you can also add only selected questions.
      • Once in the quiz you will have the opportunity to reorder the questions or to delete some of them.
      • If you want to remind yourself of the content of the question (and double check connectivity with the opaque server) click on the spy glass.
    • Continue to populate the remaining quizzes. The setdef2quiz script has placed each WeBWorK homework set in a separate category, making it somewhat easier to recreate each homework set as a quiz in Moodle.
    • While tedious, the process proceeds quickly. Be careful not to lose track of where you are. While one can add many questions to a quiz at one time questions must be deleted individually if you make a mistake.
  • You have completed transferring the questions from the homework sets in the original WeBWorK course to quizzes in the Moodle version of the course. Now go back and adjust due dates, reorder questions, or add additional descriptions to each quiz (e. g. special instructions or overview of the learning objectives of the homework set). Remember that to edit the questions themselves one must click on the “Edit questions” gear in the left margin – by default clicking on the quiz brings up a preview of the quiz.

What can possibly go wrong?
  • One potential frustration when creating quizzes and quiz engines is that it can be difficult to undo some of the choices. This is on purpose and a good thing. A question used in a quiz that has been viewed by a student cannot be deleted. You can’t delete a category if it has questions in it that are used by quizzes. (You can move those questions to another category – e.g. “Trash” and delete them later after you have removed the quizzes.)

Question engines cannot be deleted if there is still a question using that engine. If the engine can be deleted it will have an X next to its listing. The biggest problem is that it doesn’t seem to be possible to get a listing of all the questions using a given engine. Each question has a field pointing to the engine it uses but you need to inspect the questions one by one. You can change the name of a question engine (e.g. to “delete later”) so that you can ignore it for the time being. Changing the name does not change which questions use that engine.
  • With this as background it pays to plan ahead when creating the question bank in a new course since correcting mistakes can be time consuming.
  • If you are transferring questions from WeBWorK the best approach is to prescribe the engineName, the toplevel category, the engine url and the base course when calling the script . Make sure that objects with these names don’t already exist in the course and allow the act of importing the questions to automatically create both the engineName and the Category. (The subcategories of sets are created automatically by
  • You can import to an existing category in some cases but the added questions will not replace existing questions – even if they have the same name. Sometimes a new category with the same name is created which causes confusion. A better strategy is to import new questions into their own brand new temporary category and then move the imported questions into the existing category. Then delete the temporary category.
  • If the imported questions have an engineName which already exists and the engine url and the base course are identical then the existing engine is used. Otherwise a new engine is created – and if it has the same name as the existing engine then it is very confusing as to which engine is being used by which questions. This is one of those situations which is time consuming to undo.
  • There are some things which can be changed easily. You can change the engineName, url and base course with out affecting the questions using the engine. This is useful if you have to change the site of the opaque server.
  • When the questions are uploaded new categories are created along with new engines (if the categories and engines didn’t already exist).
  • In the case where I accidentally created two categories with the same name the only solution I found was to delete the extra category and upload it again with a distinctive name. Do this BEFORE you create any quizzes. Once a question has been used in a quiz it cannot be deleted until the quiz itself is deleted. There are good reasons to be cautious about deleting items but it can also be frustrating, particularly the first time you create a course.

You have set up a Moodle course, transferred homework sets to companion quizzes in this course. At this point you can tweak the course by adding open dates and due dates and descriptions for each quiz. You can experiment with using different quiz behaviors. The Moodle quiz has greater flexibility than the WeBWorK “homework” assignment and “gateway” quiz although the behaviours are not identical. 


  1. Greetings,
    I read your articles on this topic with considerable interest. First of all, thank you for your public domain efforts.
    In a production environment, is it recommended to have the WebWork server (main and opaque) on the same Linux machine as the Moodle server? If not, how does the authentication work between the 2 servers? In your writeup I don't see where the account credentials are passed for authentication on your test server.
    Madhu Avasarala

  2. BlueHost is one of the best hosting provider for any hosting services you require.

  3. I have first time heard about this engine which you have mentioned here and I also did not know about it when it was prepared in Open University In England, thanks for providing this information,
    dissertation writing service