SmartAPI
Open Source .NET RQL library for RedDot CMS / OpenText WSM Management Server
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Pages
IProjectImportJob.cs
Go to the documentation of this file.
1 ï»¿// SmartAPI - .Net programmatic access to RedDot servers
2 //
3 // Copyright (C) 2013 erminas GbR
4 //
5 // This program is free software: you can redistribute it and/or modify it
6 // under the terms of the GNU General Public License as published by the Free Software Foundation,
7 // either version 3 of the License, or (at your option) any later version.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 // See the GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License along with this program.
14 // If not, see <http://www.gnu.org/licenses/>.
15 
16 using System;
17 using System.Linq;
18 using System.Security;
19 using System.Xml;
20 using erminas.SmartAPI.CMS.ServerManagement;
21 using erminas.SmartAPI.Exceptions;
22 using erminas.SmartAPI.Utils;
23 using erminas.SmartAPI.Utils.CachedCollections;
24 
25 namespace erminas.SmartAPI.CMS.Project
26 {
28  {
29  DoNotImport = 0,
30  ImportWithoutReplacingExistingUsers = 1,
31  ImportAndReplaceExistingUsers = 2
32  }
33 
34  public interface IProjectImportJob : IAsyncJob
35  {
36  string DatabaseName { get; set; }
37  IDatabaseServer DatabaseServer { get; set; }
38  string ImportFolder { get; set; }
39  IApplicationServer ImportServer { get; set; }
40  bool IsImportingArchive { get; set; }
41  bool IsImportingReleases { get; set; }
42  bool IsIncludingAdministratorSettings { get; set; }
43  string ProjectName { get; }
44  NewProjectType ProjectType { get; set; }
45  UserGroupAndAssignments UserGroupAndAssignmentsSettings { get; set; }
46  }
47 
48  internal class ProjectImportJob : AbstractAsyncJob, IProjectImportJob
49  {
50  private readonly string _newProjectName;
51 
52  internal ProjectImportJob(ISession session, string newProjectName, string importFolder) : base(session)
53  {
54  _newProjectName = newProjectName;
55  ProjectType = NewProjectType.TestProject;
56  DatabaseServer = Session.ServerManager.DatabaseServers.First();
57  DatabaseName = _newProjectName;
58  ImportFolder = importFolder;
59  ImportServer = Session.ServerManager.ApplicationServers.First();
60  EmailSubject = "Project import completed";
61  EmailMessage = "Project import completed";
62  }
63 
64  public string DatabaseName { get; set; }
65  public IDatabaseServer DatabaseServer { get; set; }
66  public string ImportFolder { get; set; }
67  public IApplicationServer ImportServer { get; set; }
68  public bool IsImportingArchive { get; set; }
69  public bool IsImportingReleases { get; set; }
70  public bool IsIncludingAdministratorSettings { get; set; }
71 
72  public string ProjectName
73  {
74  get { return _newProjectName; }
75  }
76 
77  public NewProjectType ProjectType { get; set; }
78 
79  public override void RunAsync()
80  {
81  CheckImport();
82  ExecuteImport();
83  }
84 
85  public override void RunSync(TimeSpan maxWait)
86  {
87  RunAsync();
88  var retryEverySecond = new TimeSpan(0, 0, 1);
89  Predicate<IRDList<IAsynchronousProcess>> hasImportProcess =
90  list => list.Any(process => process.Type == AsynchronousProcessType.XMLImport);
91 
92  //wait for the async process to spawn first and then wait until it is done
93 
94  var start = DateTime.Now;
95 
96  Func<bool> hasImportProcessOrProjectIsAlreadyImported =
97  () =>
98  hasImportProcess(Session.ServerManager.AsynchronousProcesses.Refreshed()) ||
99  Session.ServerManager.Projects.Refreshed().ContainsName(ProjectName);
100  Wait.For(hasImportProcessOrProjectIsAlreadyImported, maxWait, retryEverySecond);
101 
102  if (Session.ServerManager.Projects.ContainsName(ProjectName))
103  {
104  return;
105  }
106 
107  TimeSpan timeLeft = maxWait - (DateTime.Now - start);
108  timeLeft = timeLeft.TotalMilliseconds > 0 ? timeLeft : new TimeSpan(0, 0, 0);
109 
110  Session.ServerManager.AsynchronousProcesses.WaitFor(list => !hasImportProcess(list), timeLeft,
111  retryEverySecond);
112  }
113 
114  public UserGroupAndAssignments UserGroupAndAssignmentsSettings { get; set; }
115 
116  private void CheckImport()
117  {
118  //older RedDot versions don't support the checkbeforeimport command
119  //TODO kann das auf 10er server auch gemacht werden?
120 
121  if (Session.ServerVersion < new Version(11, 0))
122  {
123  return;
124  }
125 
126  const string CHECK_IMPORT =
127  @"<ADMINISTRATION><PROJECT action=""checkbeforeimport"" xmlpath=""{0}"" /></ADMINISTRATION>";
128  var xmlDoc = Session.ExecuteRQL(CHECK_IMPORT.RQLFormat(SecurityElement.Escape(ImportFolder)),
129  RQL.IODataFormat.LogonGuidOnly);
130  Guid projectGuid;
131  XmlElement projectElement = xmlDoc.GetSingleElement("PROJECT");
132  if (projectElement == null || !projectElement.TryGetGuid(out projectGuid))
133  {
134  throw new SmartAPIException(Session.ServerLogin,
135  string.Format(
136  "Could not import project from {0}, please check folder/share permissions.",
137  ImportFolder));
138  }
139  }
140 
141  private void ExecuteImport()
142  {
143  const string IMPORT_PROJECT = @"<ADMINISTRATION>
144  <PROJECT action=""import"" userguid=""{0}"" databaseserver=""{1}"" editorialserver=""{2}"" databasename=""{3}""
145  emailnotification=""{4}"" includearchive=""{5}"" projectname=""{6}"" xmlpath=""{7}"" schema="""" schemapassword=""""
146  reddotserverguid=""{8}"" testproject=""{9}"" useoldguid=""0"" importusers=""{10}"" importobjectrelease=""{11}""
147  projectguid="""" to=""{12}"" provider="""" subject=""{13}"" message=""{14}""/>
148  </ADMINISTRATION>";
149  var query = IMPORT_PROJECT.RQLFormat(Session.CurrentUser, DatabaseServer, Server,
150  SecurityElement.Escape(DatabaseName), IsSendingEmailOnCompletion,
151  IsImportingArchive, SecurityElement.Escape(ProjectName), ImportFolder,
152  ImportServer, (int) ProjectType, (int) UserGroupAndAssignmentsSettings,
153  IsImportingReleases, EmailReceipient,
154  SecurityElement.Escape(EmailSubject),
155  SecurityElement.Escape(EmailMessage));
156 
157  Session.ExecuteRQL(query, RQL.IODataFormat.LogonGuidOnly);
158  }
159  }
160 }