1+ package com .structurizr .cli ;
2+
3+ import com .structurizr .api .AdminApiClient ;
4+ import com .structurizr .api .WorkspaceApiClient ;
5+ import com .structurizr .api .WorkspaceMetadata ;
6+ import com .structurizr .util .StringUtils ;
7+ import org .apache .commons .cli .*;
8+ import org .apache .commons .logging .Log ;
9+ import org .apache .commons .logging .LogFactory ;
10+
11+ import java .io .File ;
12+ import java .io .FileWriter ;
13+ import java .nio .file .Files ;
14+ import java .util .List ;
15+ import java .util .Properties ;
16+
17+ class BackupCommand extends AbstractCommand {
18+
19+ private static final Log log = LogFactory .getLog (BackupCommand .class );
20+
21+ BackupCommand () {
22+ }
23+
24+ public void run (String ... args ) throws Exception {
25+ Options options = new Options ();
26+
27+ Option option = new Option ("url" , "structurizrApiUrl" , true , "Structurizr API URL (default: https://api.structurizr.com)" );
28+ option .setRequired (false );
29+ options .addOption (option );
30+
31+ option = new Option ("key" , "apiKey" , true , "API key" );
32+ option .setRequired (true );
33+ options .addOption (option );
34+
35+ option = new Option ("user" , "username" , true , "Username (only required for cloud service)" );
36+ option .setRequired (false );
37+ options .addOption (option );
38+
39+ option = new Option ("o" , "output" , true , "Path to an output directory" );
40+ option .setRequired (false );
41+ options .addOption (option );
42+
43+ option = new Option ("debug" , "debug" , false , "Enable debug logging" );
44+ option .setRequired (false );
45+ options .addOption (option );
46+
47+ CommandLineParser commandLineParser = new DefaultParser ();
48+ HelpFormatter formatter = new HelpFormatter ();
49+
50+ String apiUrl = "" ;
51+ String username = "" ;
52+ String apiKey = "" ;
53+ boolean debug = false ;
54+ String outputPath = null ;
55+
56+ try {
57+ CommandLine cmd = commandLineParser .parse (options , args );
58+
59+ apiUrl = cmd .getOptionValue ("structurizrApiUrl" , "https://api.structurizr.com" );
60+ apiKey = cmd .getOptionValue ("apiKey" );
61+ username = cmd .getOptionValue ("username" );
62+ outputPath = cmd .getOptionValue ("output" );
63+ debug = cmd .hasOption ("debug" );
64+ } catch (ParseException e ) {
65+ log .error (e .getMessage ());
66+ formatter .printHelp ("backup" , options );
67+
68+ System .exit (1 );
69+ }
70+
71+ if (debug ) {
72+ configureDebugLogging ();
73+ }
74+
75+ File outputDir = new File (outputPath );
76+ if (outputDir .exists ()) {
77+ throw new RuntimeException ("Output directory already exists: " + outputDir .getAbsolutePath ());
78+ }
79+
80+ AdminApiClient adminApiClient = new AdminApiClient (apiUrl , username , apiKey );
81+ List <WorkspaceMetadata > workspaces = adminApiClient .getWorkspaces ();
82+
83+ if (!workspaces .isEmpty ()) {
84+ outputDir .mkdirs ();
85+
86+ File structurizrPropertiesFile = new File (outputDir , "structurizr.properties" );
87+ Files .writeString (structurizrPropertiesFile .toPath (), "structurizr.workspaces=*" );
88+ log .info (" - " + structurizrPropertiesFile .getCanonicalPath ());
89+
90+ for (WorkspaceMetadata workspaceMetadata : workspaces ) {
91+ File workspaceDirectory = new File (outputDir , "" + workspaceMetadata .getId ());
92+ workspaceDirectory .mkdirs ();
93+
94+ WorkspaceApiClient client = new WorkspaceApiClient (apiUrl , workspaceMetadata .getApiKey (), workspaceMetadata .getApiSecret ());
95+ client .setAgent (getAgent ());
96+
97+ String json = client .getWorkspaceAsJson (workspaceMetadata .getId ());
98+ File workspaceJsonFile = new File (workspaceDirectory , "workspace.json" );
99+ Files .writeString (workspaceJsonFile .toPath (), json );
100+ log .info (" - " + workspaceJsonFile .getCanonicalPath ());
101+
102+ Properties properties = new Properties ();
103+ properties .setProperty ("name" , workspaceMetadata .getName () != null ? workspaceMetadata .getName () : "" );
104+ properties .setProperty ("description" , workspaceMetadata .getDescription () != null ? workspaceMetadata .getDescription () : "" );
105+ properties .setProperty ("apiKey" , workspaceMetadata .getApiKey ());
106+ properties .setProperty ("apiSecret" , workspaceMetadata .getApiSecret ());
107+ properties .setProperty ("public" , "" + !StringUtils .isNullOrEmpty (workspaceMetadata .getPublicUrl ()));
108+ if (!StringUtils .isNullOrEmpty (workspaceMetadata .getShareableUrl ())) {
109+ properties .setProperty ("sharingToken" , workspaceMetadata .getShareableUrl ().substring (workspaceMetadata .getShareableUrl ().lastIndexOf ("/" ) + 1 ));
110+ }
111+ properties .setProperty ("clientSideEncrypted" , "" + (json .contains ("\" encryptionStrategy\" " ) && json .contains ("\" ciphertext\" " )));
112+
113+ File workspacePropertiesFile = new File (workspaceDirectory , "workspace.properties" );
114+ FileWriter fileWriter = new FileWriter (workspacePropertiesFile );
115+ properties .store (fileWriter , null );
116+ fileWriter .flush ();
117+ fileWriter .close ();
118+ log .info (" - " + workspacePropertiesFile .getCanonicalPath ());
119+ }
120+ }
121+ }
122+
123+ }
0 commit comments