Wenjun Ruan
5 months ago
committed by
GitHub
139 changed files with 6355 additions and 6832 deletions
@ -0,0 +1,34 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.dto.resources; |
||||
|
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
import org.apache.dolphinscheduler.spi.enums.ResourceType; |
||||
|
||||
import lombok.Data; |
||||
import lombok.experimental.SuperBuilder; |
||||
|
||||
@Data |
||||
@SuperBuilder |
||||
public abstract class AbstractResourceCreateRequest { |
||||
|
||||
private User loginUser; |
||||
private String parentAbsoluteDirectory; |
||||
private ResourceType type; |
||||
|
||||
} |
@ -0,0 +1,29 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.dto.resources; |
||||
|
||||
import lombok.Data; |
||||
import lombok.experimental.SuperBuilder; |
||||
|
||||
@Data |
||||
@SuperBuilder |
||||
public abstract class AbstractResourceDto { |
||||
|
||||
private String resourceAbsolutePath; |
||||
|
||||
} |
@ -0,0 +1,37 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.dto.resources; |
||||
|
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
@Data |
||||
@Builder |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class CreateDirectoryDto { |
||||
|
||||
private User loginUser; |
||||
|
||||
private String directoryAbsolutePath; |
||||
|
||||
} |
@ -0,0 +1,41 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.dto.resources; |
||||
|
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
import org.apache.dolphinscheduler.spi.enums.ResourceType; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
@Data |
||||
@Builder |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class CreateDirectoryRequest { |
||||
|
||||
private User loginUser; |
||||
|
||||
private ResourceType type; |
||||
|
||||
private String parentAbsoluteDirectory; |
||||
|
||||
private String directoryName; |
||||
} |
@ -0,0 +1,41 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.dto.resources; |
||||
|
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import org.springframework.web.multipart.MultipartFile; |
||||
|
||||
@Data |
||||
@Builder |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class CreateFileDto { |
||||
|
||||
private User loginUser; |
||||
|
||||
private String fileAbsolutePath; |
||||
|
||||
private MultipartFile file; |
||||
|
||||
} |
@ -0,0 +1,39 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.dto.resources; |
||||
|
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
@Data |
||||
@Builder |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class CreateFileFromContentDto { |
||||
|
||||
private User loginUser; |
||||
|
||||
private String fileAbsolutePath; |
||||
|
||||
private String fileContent; |
||||
|
||||
} |
@ -0,0 +1,40 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.dto.resources; |
||||
|
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
import org.apache.dolphinscheduler.spi.enums.ResourceType; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
@Data |
||||
@Builder |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class CreateFileFromContentRequest { |
||||
|
||||
private User loginUser; |
||||
private ResourceType type; |
||||
private String parentAbsoluteDirectory; |
||||
private String fileName; |
||||
private String fileContent; |
||||
|
||||
} |
@ -0,0 +1,41 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.dto.resources; |
||||
|
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
import org.apache.dolphinscheduler.spi.enums.ResourceType; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import org.springframework.web.multipart.MultipartFile; |
||||
|
||||
@Data |
||||
@Builder |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class CreateFileRequest { |
||||
|
||||
private User loginUser; |
||||
private ResourceType type; |
||||
private String parentAbsoluteDirectory; |
||||
private String fileName; |
||||
private MultipartFile file; |
||||
} |
@ -0,0 +1,36 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.dto.resources; |
||||
|
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
@Data |
||||
@Builder |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class DeleteResourceDto { |
||||
|
||||
private User loginUser; |
||||
private String resourceAbsolutePath; |
||||
|
||||
} |
@ -0,0 +1,35 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.dto.resources; |
||||
|
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
@Data |
||||
@Builder |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class DeleteResourceRequest { |
||||
|
||||
private User loginUser; |
||||
private String resourceAbsolutePath; |
||||
} |
@ -0,0 +1,36 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.dto.resources; |
||||
|
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
@Data |
||||
@Builder |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class DownloadFileDto { |
||||
|
||||
private User loginUser; |
||||
|
||||
private String fileAbsolutePath; |
||||
} |
@ -0,0 +1,37 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.dto.resources; |
||||
|
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
@Data |
||||
@Builder |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class DownloadFileRequest { |
||||
|
||||
private User loginUser; |
||||
|
||||
private String fileAbsolutePath; |
||||
|
||||
} |
@ -0,0 +1,38 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.dto.resources; |
||||
|
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
@Data |
||||
@Builder |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class FetchFileContentDto { |
||||
|
||||
private User loginUser; |
||||
private String resourceFileAbsolutePath; |
||||
private int skipLineNum; |
||||
private int limit; |
||||
|
||||
} |
@ -0,0 +1,37 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.dto.resources; |
||||
|
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
@Data |
||||
@Builder |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class FetchFileContentRequest { |
||||
|
||||
private User loginUser; |
||||
private String resourceFileAbsolutePath; |
||||
private int skipLineNum; |
||||
private int limit; |
||||
} |
@ -0,0 +1,58 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.dto.resources; |
||||
|
||||
import org.apache.dolphinscheduler.api.enums.Status; |
||||
import org.apache.dolphinscheduler.api.exceptions.ServiceException; |
||||
import org.apache.dolphinscheduler.common.constants.Constants; |
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
import org.apache.dolphinscheduler.spi.enums.ResourceType; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
@Data |
||||
@Builder |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class PagingResourceItemRequest { |
||||
|
||||
private User loginUser; |
||||
|
||||
private String resourceAbsolutePath; |
||||
|
||||
private ResourceType resourceType; |
||||
|
||||
private String resourceNameKeyWord; |
||||
|
||||
Integer pageNo; |
||||
|
||||
Integer pageSize; |
||||
|
||||
public void checkPageNoAndPageSize() { |
||||
if (pageNo <= 0) { |
||||
throw new ServiceException(Status.REQUEST_PARAMS_NOT_VALID_ERROR, Constants.PAGE_NUMBER); |
||||
} |
||||
if (pageSize <= 0) { |
||||
throw new ServiceException(Status.REQUEST_PARAMS_NOT_VALID_ERROR, Constants.PAGE_SIZE); |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,34 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.dto.resources; |
||||
|
||||
import java.util.List; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
@Data |
||||
@Builder |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class QueryResourceDto { |
||||
|
||||
private List<String> resourceAbsolutePaths; |
||||
} |
@ -0,0 +1,39 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.dto.resources; |
||||
|
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
@Data |
||||
@Builder |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class RenameDirectoryDto { |
||||
|
||||
private User loginUser; |
||||
|
||||
private String originDirectoryAbsolutePath; |
||||
|
||||
private String targetDirectoryAbsolutePath; |
||||
|
||||
} |
@ -0,0 +1,39 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.dto.resources; |
||||
|
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
@Data |
||||
@Builder |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class RenameDirectoryRequest { |
||||
|
||||
private User loginUser; |
||||
|
||||
private String directoryAbsolutePath; |
||||
|
||||
private String newDirectoryName; |
||||
|
||||
} |
@ -0,0 +1,38 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.dto.resources; |
||||
|
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
@Data |
||||
@Builder |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class RenameFileDto { |
||||
|
||||
private User loginUser; |
||||
|
||||
private String originFileAbsolutePath; |
||||
|
||||
private String targetFileAbsolutePath; |
||||
} |
@ -0,0 +1,39 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.dto.resources; |
||||
|
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
@Data |
||||
@Builder |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class RenameFileRequest { |
||||
|
||||
private User loginUser; |
||||
|
||||
private String fileAbsolutePath; |
||||
|
||||
private String newFileName; |
||||
|
||||
} |
@ -0,0 +1,41 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.dto.resources; |
||||
|
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import org.springframework.web.multipart.MultipartFile; |
||||
|
||||
@Data |
||||
@Builder |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class UpdateFileDto { |
||||
|
||||
private User loginUser; |
||||
|
||||
private String fileAbsolutePath; |
||||
|
||||
private MultipartFile file; |
||||
|
||||
} |
@ -0,0 +1,39 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.dto.resources; |
||||
|
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
@Data |
||||
@Builder |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class UpdateFileFromContentDto { |
||||
|
||||
private User loginUser; |
||||
|
||||
private String fileAbsolutePath; |
||||
|
||||
private String fileContent; |
||||
|
||||
} |
@ -0,0 +1,39 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.dto.resources; |
||||
|
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
@Data |
||||
@Builder |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class UpdateFileFromContentRequest { |
||||
|
||||
private User loginUser; |
||||
|
||||
private String fileAbsolutePath; |
||||
|
||||
private String fileContent; |
||||
|
||||
} |
@ -0,0 +1,41 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.dto.resources; |
||||
|
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import org.springframework.web.multipart.MultipartFile; |
||||
|
||||
@Data |
||||
@Builder |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class UpdateFileRequest { |
||||
|
||||
private User loginUser; |
||||
|
||||
private String fileAbsolutePath; |
||||
|
||||
private MultipartFile file; |
||||
|
||||
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,24 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.validator; |
||||
|
||||
public interface ITransformer<T, R> { |
||||
|
||||
R transform(T t); |
||||
|
||||
} |
@ -0,0 +1,24 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.validator; |
||||
|
||||
public interface IValidator<T> { |
||||
|
||||
void validate(T t); |
||||
|
||||
} |
@ -0,0 +1,56 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.validator.resource; |
||||
|
||||
import org.apache.dolphinscheduler.api.enums.Status; |
||||
import org.apache.dolphinscheduler.api.exceptions.ServiceException; |
||||
import org.apache.dolphinscheduler.api.validator.ITransformer; |
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
import org.apache.dolphinscheduler.dao.repository.TenantDao; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.StorageOperator; |
||||
import org.apache.dolphinscheduler.spi.enums.ResourceType; |
||||
|
||||
import org.apache.commons.lang3.StringUtils; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
|
||||
@AllArgsConstructor |
||||
public abstract class AbstractResourceTransformer<T, R> implements ITransformer<T, R> { |
||||
|
||||
protected TenantDao tenantDao; |
||||
|
||||
protected StorageOperator storageOperator; |
||||
|
||||
protected String getParentDirectoryAbsolutePath(User loginUser, String parentAbsoluteDirectory, ResourceType type) { |
||||
String tenantCode = tenantDao.queryOptionalById(loginUser.getTenantId()) |
||||
.orElseThrow(() -> new ServiceException(Status.CURRENT_LOGIN_USER_TENANT_NOT_EXIST)) |
||||
.getTenantCode(); |
||||
String userResRootPath = storageOperator.getStorageBaseDirectory(tenantCode, type); |
||||
// If the parent directory is / then will transform to userResRootPath
|
||||
// This only happens when the front-end go into the resource page first
|
||||
// todo: we need to change the front-end logic to avoid this
|
||||
if (parentAbsoluteDirectory.equals("/")) { |
||||
return userResRootPath; |
||||
} |
||||
|
||||
if (!StringUtils.startsWith(parentAbsoluteDirectory, userResRootPath)) { |
||||
throw new ServiceException(Status.ILLEGAL_RESOURCE_PATH, parentAbsoluteDirectory); |
||||
} |
||||
return parentAbsoluteDirectory; |
||||
} |
||||
} |
@ -0,0 +1,138 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.validator.resource; |
||||
|
||||
import org.apache.dolphinscheduler.api.dto.resources.AbstractResourceDto; |
||||
import org.apache.dolphinscheduler.api.enums.Status; |
||||
import org.apache.dolphinscheduler.api.exceptions.ServiceException; |
||||
import org.apache.dolphinscheduler.api.validator.IValidator; |
||||
import org.apache.dolphinscheduler.common.enums.UserType; |
||||
import org.apache.dolphinscheduler.common.utils.FileUtils; |
||||
import org.apache.dolphinscheduler.dao.entity.Tenant; |
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
import org.apache.dolphinscheduler.dao.repository.TenantDao; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.ResourceMetadata; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.StorageOperator; |
||||
|
||||
import org.apache.commons.lang3.StringUtils; |
||||
|
||||
import java.util.Arrays; |
||||
import java.util.HashSet; |
||||
import java.util.Set; |
||||
|
||||
import org.springframework.web.multipart.MultipartFile; |
||||
|
||||
import com.google.common.io.Files; |
||||
|
||||
public abstract class AbstractResourceValidator<T> implements IValidator<T> { |
||||
|
||||
private static final Set<String> FILE_SUFFIXES_WHICH_CAN_FETCH_CONTENT = new HashSet<>(Arrays.asList( |
||||
StringUtils.defaultIfBlank(FileUtils.getResourceViewSuffixes(), "").split(","))); |
||||
|
||||
protected final StorageOperator storageOperator; |
||||
|
||||
private final TenantDao tenantDao; |
||||
|
||||
public AbstractResourceValidator(StorageOperator storageOperator, TenantDao tenantDao) { |
||||
this.storageOperator = storageOperator; |
||||
this.tenantDao = tenantDao; |
||||
} |
||||
|
||||
public void exceptionResourceAbsolutePathInvalidated(String resourceAbsolutePath) { |
||||
if (StringUtils.isBlank(resourceAbsolutePath)) { |
||||
throw new ServiceException("The resource path is null"); |
||||
} |
||||
if (!resourceAbsolutePath.startsWith(storageOperator.getStorageBaseDirectory())) { |
||||
throw new ServiceException("Invalidated resource path: " + resourceAbsolutePath); |
||||
} |
||||
if (resourceAbsolutePath.contains("..")) { |
||||
throw new ServiceException("Invalidated resource path: " + resourceAbsolutePath); |
||||
} |
||||
} |
||||
|
||||
public void exceptionFileInvalidated(MultipartFile file) { |
||||
if (file == null) { |
||||
throw new ServiceException("The file is null"); |
||||
} |
||||
} |
||||
|
||||
public void exceptionFileContentInvalidated(String fileContent) { |
||||
if (StringUtils.isEmpty(fileContent)) { |
||||
throw new ServiceException("The file content is null"); |
||||
} |
||||
} |
||||
|
||||
public void exceptionFileContentCannotFetch(String fileAbsolutePath) { |
||||
String fileExtension = Files.getFileExtension(fileAbsolutePath); |
||||
if (!FILE_SUFFIXES_WHICH_CAN_FETCH_CONTENT.contains(fileExtension)) { |
||||
throw new ServiceException("The file type: " + fileExtension + " cannot be fetched"); |
||||
} |
||||
} |
||||
|
||||
public void exceptionResourceNotExists(String resourceAbsolutePath) { |
||||
if (!storageOperator.exists(resourceAbsolutePath)) { |
||||
throw new ServiceException("Thr resource is not exists: " + resourceAbsolutePath); |
||||
} |
||||
} |
||||
|
||||
public void exceptionResourceExists(String resourceAbsolutePath) { |
||||
if (storageOperator.exists(resourceAbsolutePath)) { |
||||
throw new ServiceException("The resource is already exist: " + resourceAbsolutePath); |
||||
} |
||||
} |
||||
|
||||
public void exceptionResourceIsNotDirectory(String resourceAbsolutePath) { |
||||
if (StringUtils.isNotEmpty(Files.getFileExtension(resourceAbsolutePath))) { |
||||
throw new ServiceException("The path is not a directory: " + resourceAbsolutePath); |
||||
} |
||||
} |
||||
|
||||
public void exceptionResourceIsNotFile(String fileAbsolutePath) { |
||||
if (StringUtils.isEmpty(Files.getFileExtension(fileAbsolutePath))) { |
||||
throw new ServiceException("The path is not a file: " + fileAbsolutePath); |
||||
} |
||||
} |
||||
|
||||
public void exceptionUserNoResourcePermission(User user, AbstractResourceDto resourceDto) { |
||||
exceptionUserNoResourcePermission(user, resourceDto.getResourceAbsolutePath()); |
||||
} |
||||
|
||||
public void exceptionUserNoResourcePermission(User user, String resourceAbsolutePath) { |
||||
if (user.getUserType() == UserType.ADMIN_USER) { |
||||
return; |
||||
} |
||||
// check if the user have resource tenant permission
|
||||
// Parse the resource path to get the tenant code
|
||||
ResourceMetadata resourceMetaData = storageOperator.getResourceMetaData(resourceAbsolutePath); |
||||
|
||||
if (!resourceAbsolutePath.startsWith(resourceMetaData.getResourceBaseDirectory())) { |
||||
throw new ServiceException("Invalidated resource path: " + resourceAbsolutePath); |
||||
} |
||||
|
||||
// todo: inject the tenant when login
|
||||
Tenant tenant = tenantDao.queryOptionalById(user.getTenantId()) |
||||
.orElseThrow(() -> new ServiceException(Status.TENANT_NOT_EXIST, user.getTenantId())); |
||||
String userTenant = tenant.getTenantCode(); |
||||
if (!userTenant.equals(resourceMetaData.getTenant())) { |
||||
throw new ServiceException( |
||||
"The user's tenant is " + userTenant + " have no permission to access the resource: " |
||||
+ resourceAbsolutePath); |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,50 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.validator.resource; |
||||
|
||||
import org.apache.dolphinscheduler.api.dto.resources.CreateDirectoryDto; |
||||
import org.apache.dolphinscheduler.api.exceptions.ServiceException; |
||||
import org.apache.dolphinscheduler.dao.repository.TenantDao; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.StorageOperator; |
||||
|
||||
import org.apache.commons.lang3.StringUtils; |
||||
|
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import com.google.common.io.Files; |
||||
|
||||
@Component |
||||
public class CreateDirectoryDtoValidator extends AbstractResourceValidator<CreateDirectoryDto> { |
||||
|
||||
public CreateDirectoryDtoValidator(StorageOperator storageOperator, TenantDao tenantDao) { |
||||
super(storageOperator, tenantDao); |
||||
} |
||||
|
||||
@Override |
||||
public void validate(CreateDirectoryDto createDirectoryDto) { |
||||
String directoryAbsolutePath = createDirectoryDto.getDirectoryAbsolutePath(); |
||||
|
||||
exceptionResourceAbsolutePathInvalidated(directoryAbsolutePath); |
||||
exceptionResourceExists(directoryAbsolutePath); |
||||
exceptionUserNoResourcePermission(createDirectoryDto.getLoginUser(), directoryAbsolutePath); |
||||
exceptionResourceIsNotDirectory(directoryAbsolutePath); |
||||
if (StringUtils.isNotEmpty(Files.getFileExtension(directoryAbsolutePath))) { |
||||
throw new ServiceException("The path is not a directory: " + directoryAbsolutePath); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,87 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.validator.resource; |
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull; |
||||
|
||||
import org.apache.dolphinscheduler.api.dto.resources.CreateDirectoryDto; |
||||
import org.apache.dolphinscheduler.api.dto.resources.CreateDirectoryRequest; |
||||
import org.apache.dolphinscheduler.api.enums.Status; |
||||
import org.apache.dolphinscheduler.api.exceptions.ServiceException; |
||||
import org.apache.dolphinscheduler.api.validator.ITransformer; |
||||
import org.apache.dolphinscheduler.common.utils.FileUtils; |
||||
import org.apache.dolphinscheduler.dao.repository.TenantDao; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.StorageOperator; |
||||
|
||||
import org.apache.commons.lang3.StringUtils; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
@Component |
||||
public class CreateDirectoryRequestTransformer implements ITransformer<CreateDirectoryRequest, CreateDirectoryDto> { |
||||
|
||||
@Autowired |
||||
private TenantDao tenantDao; |
||||
|
||||
@Autowired |
||||
private StorageOperator storageOperator; |
||||
|
||||
@Override |
||||
public CreateDirectoryDto transform(CreateDirectoryRequest createDirectoryRequest) { |
||||
validateCreateDirectoryRequest(createDirectoryRequest); |
||||
return doTransform(createDirectoryRequest); |
||||
} |
||||
|
||||
private CreateDirectoryDto doTransform(CreateDirectoryRequest createDirectoryRequest) { |
||||
String directoryAbsolutePath = getDirectoryAbsolutePath(createDirectoryRequest); |
||||
return CreateDirectoryDto.builder() |
||||
.loginUser(createDirectoryRequest.getLoginUser()) |
||||
.directoryAbsolutePath(directoryAbsolutePath) |
||||
.build(); |
||||
} |
||||
|
||||
private void validateCreateDirectoryRequest(CreateDirectoryRequest createDirectoryRequest) { |
||||
checkNotNull(createDirectoryRequest.getLoginUser(), "loginUser is null"); |
||||
checkNotNull(createDirectoryRequest.getType(), "resource type is null"); |
||||
checkNotNull(createDirectoryRequest.getDirectoryName(), "directory name is null"); |
||||
checkNotNull(createDirectoryRequest.getParentAbsoluteDirectory(), "parent directory is null"); |
||||
|
||||
} |
||||
|
||||
private String getDirectoryAbsolutePath(CreateDirectoryRequest createDirectoryRequest) { |
||||
String tenantCode = tenantDao.queryOptionalById(createDirectoryRequest.getLoginUser().getTenantId()) |
||||
.orElseThrow(() -> new ServiceException(Status.CURRENT_LOGIN_USER_TENANT_NOT_EXIST)) |
||||
.getTenantCode(); |
||||
String userResRootPath = storageOperator.getStorageBaseDirectory(tenantCode, createDirectoryRequest.getType()); |
||||
String parentDirectoryName = createDirectoryRequest.getParentAbsoluteDirectory(); |
||||
String directoryName = createDirectoryRequest.getDirectoryName(); |
||||
|
||||
// If the parent directory is / then will transform to userResRootPath
|
||||
// This only happens when the front-end go into the resource page first
|
||||
// todo: we need to change the front-end logic to avoid this
|
||||
if (parentDirectoryName.equals("/")) { |
||||
return FileUtils.concatFilePath(userResRootPath, directoryName); |
||||
} |
||||
|
||||
if (!StringUtils.startsWith(parentDirectoryName, userResRootPath)) { |
||||
throw new ServiceException(Status.ILLEGAL_RESOURCE_PATH, parentDirectoryName); |
||||
} |
||||
return FileUtils.concatFilePath(parentDirectoryName, directoryName); |
||||
} |
||||
} |
@ -0,0 +1,47 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.validator.resource; |
||||
|
||||
import org.apache.dolphinscheduler.api.dto.resources.CreateFileDto; |
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
import org.apache.dolphinscheduler.dao.repository.TenantDao; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.StorageOperator; |
||||
|
||||
import org.springframework.stereotype.Component; |
||||
import org.springframework.web.multipart.MultipartFile; |
||||
|
||||
@Component |
||||
public class CreateFileDtoValidator extends AbstractResourceValidator<CreateFileDto> { |
||||
|
||||
public CreateFileDtoValidator(StorageOperator storageOperator, TenantDao tenantDao) { |
||||
super(storageOperator, tenantDao); |
||||
} |
||||
|
||||
@Override |
||||
public void validate(CreateFileDto createFileDto) { |
||||
String fileAbsolutePath = createFileDto.getFileAbsolutePath(); |
||||
User loginUser = createFileDto.getLoginUser(); |
||||
MultipartFile file = createFileDto.getFile(); |
||||
|
||||
exceptionResourceAbsolutePathInvalidated(fileAbsolutePath); |
||||
exceptionResourceExists(fileAbsolutePath); |
||||
exceptionFileInvalidated(file); |
||||
exceptionUserNoResourcePermission(loginUser, fileAbsolutePath); |
||||
exceptionResourceIsNotFile(fileAbsolutePath); |
||||
} |
||||
} |
@ -0,0 +1,46 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.validator.resource; |
||||
|
||||
import org.apache.dolphinscheduler.api.dto.resources.CreateFileFromContentDto; |
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
import org.apache.dolphinscheduler.dao.repository.TenantDao; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.StorageOperator; |
||||
|
||||
import org.springframework.stereotype.Component; |
||||
|
||||
@Component |
||||
public class CreateFileFromContentDtoValidator extends AbstractResourceValidator<CreateFileFromContentDto> { |
||||
|
||||
public CreateFileFromContentDtoValidator(StorageOperator storageOperator, TenantDao tenantDao) { |
||||
super(storageOperator, tenantDao); |
||||
} |
||||
|
||||
@Override |
||||
public void validate(CreateFileFromContentDto createFileFromContentDto) { |
||||
String fileAbsolutePath = createFileFromContentDto.getFileAbsolutePath(); |
||||
User loginUser = createFileFromContentDto.getLoginUser(); |
||||
String fileContent = createFileFromContentDto.getFileContent(); |
||||
|
||||
exceptionResourceAbsolutePathInvalidated(fileAbsolutePath); |
||||
exceptionResourceIsNotFile(fileAbsolutePath); |
||||
exceptionResourceExists(fileAbsolutePath); |
||||
exceptionUserNoResourcePermission(loginUser, fileAbsolutePath); |
||||
exceptionFileContentInvalidated(fileContent); |
||||
} |
||||
} |
@ -0,0 +1,43 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.validator.resource; |
||||
|
||||
import org.apache.dolphinscheduler.api.dto.resources.DeleteResourceDto; |
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
import org.apache.dolphinscheduler.dao.repository.TenantDao; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.StorageOperator; |
||||
|
||||
import org.springframework.stereotype.Component; |
||||
|
||||
@Component |
||||
public class DeleteResourceDtoValidator extends AbstractResourceValidator<DeleteResourceDto> { |
||||
|
||||
public DeleteResourceDtoValidator(StorageOperator storageOperator, TenantDao tenantDao) { |
||||
super(storageOperator, tenantDao); |
||||
} |
||||
|
||||
@Override |
||||
public void validate(DeleteResourceDto deleteResourceDto) { |
||||
String resourceAbsolutePath = deleteResourceDto.getResourceAbsolutePath(); |
||||
User loginUser = deleteResourceDto.getLoginUser(); |
||||
|
||||
exceptionResourceAbsolutePathInvalidated(resourceAbsolutePath); |
||||
exceptionResourceNotExists(resourceAbsolutePath); |
||||
exceptionUserNoResourcePermission(loginUser, resourceAbsolutePath); |
||||
} |
||||
} |
@ -0,0 +1,44 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.validator.resource; |
||||
|
||||
import org.apache.dolphinscheduler.api.dto.resources.DownloadFileDto; |
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
import org.apache.dolphinscheduler.dao.repository.TenantDao; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.StorageOperator; |
||||
|
||||
import org.springframework.stereotype.Component; |
||||
|
||||
@Component |
||||
public class DownloadFileDtoValidator extends AbstractResourceValidator<DownloadFileDto> { |
||||
|
||||
public DownloadFileDtoValidator(StorageOperator storageOperator, TenantDao tenantDao) { |
||||
super(storageOperator, tenantDao); |
||||
} |
||||
|
||||
@Override |
||||
public void validate(DownloadFileDto downloadFileDto) { |
||||
String fileAbsolutePath = downloadFileDto.getFileAbsolutePath(); |
||||
User loginUser = downloadFileDto.getLoginUser(); |
||||
|
||||
exceptionResourceNotExists(fileAbsolutePath); |
||||
exceptionResourceAbsolutePathInvalidated(fileAbsolutePath); |
||||
exceptionResourceIsNotFile(fileAbsolutePath); |
||||
exceptionUserNoResourcePermission(loginUser, fileAbsolutePath); |
||||
} |
||||
} |
@ -0,0 +1,48 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.validator.resource; |
||||
|
||||
import org.apache.dolphinscheduler.api.dto.resources.FetchFileContentDto; |
||||
import org.apache.dolphinscheduler.api.exceptions.ServiceException; |
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
import org.apache.dolphinscheduler.dao.repository.TenantDao; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.StorageOperator; |
||||
|
||||
import org.springframework.stereotype.Component; |
||||
|
||||
@Component |
||||
public class FetchFileContentDtoValidator extends AbstractResourceValidator<FetchFileContentDto> { |
||||
|
||||
public FetchFileContentDtoValidator(StorageOperator storageOperator, TenantDao tenantDao) { |
||||
super(storageOperator, tenantDao); |
||||
} |
||||
|
||||
@Override |
||||
public void validate(FetchFileContentDto fetchFileContentDto) { |
||||
if (fetchFileContentDto.getSkipLineNum() < 0) { |
||||
throw new ServiceException("skipLineNum must be greater than or equal to 0"); |
||||
} |
||||
String resourceFileAbsolutePath = fetchFileContentDto.getResourceFileAbsolutePath(); |
||||
User loginUser = fetchFileContentDto.getLoginUser(); |
||||
|
||||
exceptionResourceAbsolutePathInvalidated(resourceFileAbsolutePath); |
||||
exceptionResourceIsNotFile(resourceFileAbsolutePath); |
||||
exceptionUserNoResourcePermission(loginUser, resourceFileAbsolutePath); |
||||
exceptionFileContentCannotFetch(resourceFileAbsolutePath); |
||||
} |
||||
} |
@ -0,0 +1,71 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.validator.resource; |
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull; |
||||
|
||||
import org.apache.dolphinscheduler.api.dto.resources.CreateFileFromContentDto; |
||||
import org.apache.dolphinscheduler.api.dto.resources.CreateFileFromContentRequest; |
||||
import org.apache.dolphinscheduler.common.utils.FileUtils; |
||||
import org.apache.dolphinscheduler.dao.repository.TenantDao; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.StorageOperator; |
||||
|
||||
import org.springframework.stereotype.Component; |
||||
|
||||
@Component |
||||
public class FileFromContentRequestTransformer |
||||
extends |
||||
AbstractResourceTransformer<CreateFileFromContentRequest, CreateFileFromContentDto> { |
||||
|
||||
public FileFromContentRequestTransformer(TenantDao tenantDao, StorageOperator storageOperator) { |
||||
super(tenantDao, storageOperator); |
||||
} |
||||
|
||||
@Override |
||||
public CreateFileFromContentDto transform(CreateFileFromContentRequest createFileFromContentRequest) { |
||||
validateCreateFileRequest(createFileFromContentRequest); |
||||
return doTransform(createFileFromContentRequest); |
||||
} |
||||
|
||||
private void validateCreateFileRequest(CreateFileFromContentRequest createFileFromContentRequest) { |
||||
checkNotNull(createFileFromContentRequest.getLoginUser(), "loginUser is null"); |
||||
checkNotNull(createFileFromContentRequest.getType(), "resource type is null"); |
||||
checkNotNull(createFileFromContentRequest.getFileName(), "file name is null"); |
||||
checkNotNull(createFileFromContentRequest.getParentAbsoluteDirectory(), "parent directory is null"); |
||||
checkNotNull(createFileFromContentRequest.getFileContent(), "file content is null"); |
||||
} |
||||
|
||||
private CreateFileFromContentDto doTransform(CreateFileFromContentRequest createFileFromContentRequest) { |
||||
String fileAbsolutePath = getFileAbsolutePath(createFileFromContentRequest); |
||||
return CreateFileFromContentDto.builder() |
||||
.loginUser(createFileFromContentRequest.getLoginUser()) |
||||
.fileAbsolutePath(fileAbsolutePath) |
||||
.fileContent(createFileFromContentRequest.getFileContent()) |
||||
.build(); |
||||
|
||||
} |
||||
|
||||
private String getFileAbsolutePath(CreateFileFromContentRequest createFileFromContentRequest) { |
||||
String parentDirectoryAbsolutePath = getParentDirectoryAbsolutePath( |
||||
createFileFromContentRequest.getLoginUser(), |
||||
createFileFromContentRequest.getParentAbsoluteDirectory(), |
||||
createFileFromContentRequest.getType()); |
||||
return FileUtils.concatFilePath(parentDirectoryAbsolutePath, createFileFromContentRequest.getFileName()); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,68 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.validator.resource; |
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull; |
||||
|
||||
import org.apache.dolphinscheduler.api.dto.resources.CreateFileDto; |
||||
import org.apache.dolphinscheduler.api.dto.resources.CreateFileRequest; |
||||
import org.apache.dolphinscheduler.common.utils.FileUtils; |
||||
import org.apache.dolphinscheduler.dao.repository.TenantDao; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.StorageOperator; |
||||
|
||||
import org.springframework.stereotype.Component; |
||||
|
||||
@Component |
||||
public class FileRequestTransformer extends AbstractResourceTransformer<CreateFileRequest, CreateFileDto> { |
||||
|
||||
public FileRequestTransformer(TenantDao tenantDao, StorageOperator storageOperator) { |
||||
super(tenantDao, storageOperator); |
||||
} |
||||
|
||||
@Override |
||||
public CreateFileDto transform(CreateFileRequest createFileRequest) { |
||||
validateCreateFileRequest(createFileRequest); |
||||
return doTransform(createFileRequest); |
||||
} |
||||
|
||||
private void validateCreateFileRequest(CreateFileRequest createFileRequest) { |
||||
checkNotNull(createFileRequest.getLoginUser(), "loginUser is null"); |
||||
checkNotNull(createFileRequest.getType(), "resource type is null"); |
||||
checkNotNull(createFileRequest.getFileName(), "file name is null"); |
||||
checkNotNull(createFileRequest.getParentAbsoluteDirectory(), "parent directory is null"); |
||||
checkNotNull(createFileRequest.getFile(), "file is null"); |
||||
} |
||||
|
||||
private CreateFileDto doTransform(CreateFileRequest createFileRequest) { |
||||
String fileAbsolutePath = getFileAbsolutePath(createFileRequest); |
||||
return CreateFileDto.builder() |
||||
.loginUser(createFileRequest.getLoginUser()) |
||||
.file(createFileRequest.getFile()) |
||||
.fileAbsolutePath(fileAbsolutePath) |
||||
.build(); |
||||
|
||||
} |
||||
|
||||
private String getFileAbsolutePath(CreateFileRequest createFileRequest) { |
||||
String parentDirectoryAbsolutePath = getParentDirectoryAbsolutePath( |
||||
createFileRequest.getLoginUser(), |
||||
createFileRequest.getParentAbsoluteDirectory(), |
||||
createFileRequest.getType()); |
||||
return FileUtils.concatFilePath(parentDirectoryAbsolutePath, createFileRequest.getFileName()); |
||||
} |
||||
} |
@ -0,0 +1,90 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.validator.resource; |
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull; |
||||
|
||||
import org.apache.dolphinscheduler.api.dto.resources.PagingResourceItemRequest; |
||||
import org.apache.dolphinscheduler.api.dto.resources.QueryResourceDto; |
||||
import org.apache.dolphinscheduler.api.validator.ITransformer; |
||||
import org.apache.dolphinscheduler.common.enums.UserType; |
||||
import org.apache.dolphinscheduler.dao.entity.Tenant; |
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
import org.apache.dolphinscheduler.dao.repository.TenantDao; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.StorageOperator; |
||||
import org.apache.dolphinscheduler.spi.enums.ResourceType; |
||||
|
||||
import org.apache.commons.lang3.StringUtils; |
||||
|
||||
import java.util.List; |
||||
import java.util.stream.Collectors; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
|
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import com.google.common.collect.Lists; |
||||
|
||||
@Component |
||||
@AllArgsConstructor |
||||
public class PagingResourceItemRequestTransformer implements ITransformer<PagingResourceItemRequest, QueryResourceDto> { |
||||
|
||||
private final StorageOperator storageOperator; |
||||
|
||||
private final TenantDao tenantDao; |
||||
|
||||
@Override |
||||
public QueryResourceDto transform(PagingResourceItemRequest pagingResourceItemRequest) { |
||||
validatePagingResourceItemRequest(pagingResourceItemRequest); |
||||
|
||||
if (StringUtils.isNotEmpty(pagingResourceItemRequest.getResourceAbsolutePath())) { |
||||
// query from the given path
|
||||
return QueryResourceDto.builder() |
||||
.resourceAbsolutePaths(Lists.newArrayList(pagingResourceItemRequest.getResourceAbsolutePath())) |
||||
.build(); |
||||
} |
||||
|
||||
ResourceType resourceType = pagingResourceItemRequest.getResourceType(); |
||||
User loginUser = pagingResourceItemRequest.getLoginUser(); |
||||
if (loginUser.getUserType() == UserType.ADMIN_USER) { |
||||
// If the current user is admin
|
||||
// then will query all tenant resources
|
||||
List<String> resourceAbsolutePaths = tenantDao.queryAll() |
||||
.stream() |
||||
.map(tenant -> storageOperator.getStorageBaseDirectory(tenant.getTenantCode(), resourceType)) |
||||
.collect(Collectors.toList()); |
||||
return QueryResourceDto.builder() |
||||
.resourceAbsolutePaths(resourceAbsolutePaths) |
||||
.build(); |
||||
} else { |
||||
// todo: inject the tenantCode when login
|
||||
Tenant tenant = tenantDao.queryById(loginUser.getTenantId()); |
||||
String storageBaseDirectory = storageOperator.getStorageBaseDirectory(tenant.getTenantCode(), resourceType); |
||||
return QueryResourceDto.builder() |
||||
.resourceAbsolutePaths(Lists.newArrayList(storageBaseDirectory)) |
||||
.build(); |
||||
} |
||||
|
||||
} |
||||
|
||||
private void validatePagingResourceItemRequest(PagingResourceItemRequest pagingResourceItemRequest) { |
||||
checkNotNull(pagingResourceItemRequest.getLoginUser(), "loginUser is null"); |
||||
checkNotNull(pagingResourceItemRequest.getResourceType(), "resourceType is null"); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,50 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.validator.resource; |
||||
|
||||
import org.apache.dolphinscheduler.api.dto.resources.RenameDirectoryDto; |
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
import org.apache.dolphinscheduler.dao.repository.TenantDao; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.StorageOperator; |
||||
|
||||
import org.springframework.stereotype.Component; |
||||
|
||||
@Component |
||||
public class RenameDirectoryDtoValidator extends AbstractResourceValidator<RenameDirectoryDto> { |
||||
|
||||
public RenameDirectoryDtoValidator(StorageOperator storageOperator, TenantDao tenantDao) { |
||||
super(storageOperator, tenantDao); |
||||
} |
||||
|
||||
@Override |
||||
public void validate(RenameDirectoryDto renameDirectoryDto) { |
||||
String originDirectoryAbsolutePath = renameDirectoryDto.getOriginDirectoryAbsolutePath(); |
||||
User loginUser = renameDirectoryDto.getLoginUser(); |
||||
String targetDirectoryAbsolutePath = renameDirectoryDto.getTargetDirectoryAbsolutePath(); |
||||
|
||||
exceptionResourceAbsolutePathInvalidated(originDirectoryAbsolutePath); |
||||
exceptionResourceIsNotDirectory(originDirectoryAbsolutePath); |
||||
exceptionResourceNotExists(originDirectoryAbsolutePath); |
||||
exceptionUserNoResourcePermission(loginUser, originDirectoryAbsolutePath); |
||||
|
||||
exceptionResourceAbsolutePathInvalidated(targetDirectoryAbsolutePath); |
||||
exceptionResourceIsNotDirectory(targetDirectoryAbsolutePath); |
||||
exceptionResourceExists(targetDirectoryAbsolutePath); |
||||
exceptionUserNoResourcePermission(loginUser, targetDirectoryAbsolutePath); |
||||
} |
||||
} |
@ -0,0 +1,56 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.validator.resource; |
||||
|
||||
import org.apache.dolphinscheduler.api.dto.resources.RenameDirectoryDto; |
||||
import org.apache.dolphinscheduler.api.dto.resources.RenameDirectoryRequest; |
||||
import org.apache.dolphinscheduler.api.validator.ITransformer; |
||||
|
||||
import org.apache.commons.lang3.StringUtils; |
||||
|
||||
import java.io.File; |
||||
|
||||
import lombok.extern.slf4j.Slf4j; |
||||
|
||||
import org.springframework.stereotype.Component; |
||||
|
||||
@Slf4j |
||||
@Component |
||||
public class RenameDirectoryRequestTransformer implements ITransformer<RenameDirectoryRequest, RenameDirectoryDto> { |
||||
|
||||
@Override |
||||
public RenameDirectoryDto transform(RenameDirectoryRequest renameDirectoryRequest) { |
||||
String originDirectoryAbsolutePath = renameDirectoryRequest.getDirectoryAbsolutePath(); |
||||
String targetDirectoryName = renameDirectoryRequest.getNewDirectoryName(); |
||||
|
||||
String targetDirectoryAbsolutePath = |
||||
getTargetDirectoryAbsolutePath(originDirectoryAbsolutePath, targetDirectoryName); |
||||
|
||||
return RenameDirectoryDto.builder() |
||||
.loginUser(renameDirectoryRequest.getLoginUser()) |
||||
.originDirectoryAbsolutePath(originDirectoryAbsolutePath) |
||||
.targetDirectoryAbsolutePath(targetDirectoryAbsolutePath) |
||||
.build(); |
||||
} |
||||
|
||||
private String getTargetDirectoryAbsolutePath(String originDirectoryAbsolutePath, String targetDirectoryName) { |
||||
String originDirectoryParentAbsolutePath = StringUtils.substringBeforeLast( |
||||
originDirectoryAbsolutePath, File.separator); |
||||
return originDirectoryParentAbsolutePath + File.separator + targetDirectoryName; |
||||
} |
||||
} |
@ -0,0 +1,50 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.validator.resource; |
||||
|
||||
import org.apache.dolphinscheduler.api.dto.resources.RenameFileDto; |
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
import org.apache.dolphinscheduler.dao.repository.TenantDao; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.StorageOperator; |
||||
|
||||
import org.springframework.stereotype.Component; |
||||
|
||||
@Component |
||||
public class RenameFileDtoValidator extends AbstractResourceValidator<RenameFileDto> { |
||||
|
||||
public RenameFileDtoValidator(StorageOperator storageOperator, TenantDao tenantDao) { |
||||
super(storageOperator, tenantDao); |
||||
} |
||||
|
||||
@Override |
||||
public void validate(RenameFileDto renameFileDto) { |
||||
String originFileAbsolutePath = renameFileDto.getOriginFileAbsolutePath(); |
||||
User loginUser = renameFileDto.getLoginUser(); |
||||
String targetFileAbsolutePath = renameFileDto.getTargetFileAbsolutePath(); |
||||
|
||||
exceptionResourceAbsolutePathInvalidated(originFileAbsolutePath); |
||||
exceptionResourceNotExists(originFileAbsolutePath); |
||||
exceptionResourceIsNotFile(originFileAbsolutePath); |
||||
exceptionUserNoResourcePermission(loginUser, originFileAbsolutePath); |
||||
|
||||
exceptionResourceAbsolutePathInvalidated(targetFileAbsolutePath); |
||||
exceptionResourceExists(targetFileAbsolutePath); |
||||
exceptionResourceIsNotFile(targetFileAbsolutePath); |
||||
exceptionUserNoResourcePermission(loginUser, targetFileAbsolutePath); |
||||
} |
||||
} |
@ -0,0 +1,47 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.validator.resource; |
||||
|
||||
import org.apache.dolphinscheduler.api.dto.resources.RenameFileDto; |
||||
import org.apache.dolphinscheduler.api.dto.resources.RenameFileRequest; |
||||
import org.apache.dolphinscheduler.api.validator.ITransformer; |
||||
import org.apache.dolphinscheduler.common.utils.FileUtils; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.ResourceMetadata; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.StorageOperator; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
@Component |
||||
public class RenameFileRequestTransformer implements ITransformer<RenameFileRequest, RenameFileDto> { |
||||
|
||||
@Autowired |
||||
private StorageOperator storageOperator; |
||||
|
||||
@Override |
||||
public RenameFileDto transform(RenameFileRequest renameFileRequest) { |
||||
ResourceMetadata resourceMetaData = |
||||
storageOperator.getResourceMetaData(renameFileRequest.getFileAbsolutePath()); |
||||
return RenameFileDto.builder() |
||||
.loginUser(renameFileRequest.getLoginUser()) |
||||
.originFileAbsolutePath(renameFileRequest.getFileAbsolutePath()) |
||||
.targetFileAbsolutePath(FileUtils.concatFilePath(resourceMetaData.getResourceParentAbsolutePath(), |
||||
renameFileRequest.getNewFileName())) |
||||
.build(); |
||||
} |
||||
} |
@ -0,0 +1,57 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.validator.resource; |
||||
|
||||
import org.apache.dolphinscheduler.api.dto.resources.UpdateFileDto; |
||||
import org.apache.dolphinscheduler.api.exceptions.ServiceException; |
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
import org.apache.dolphinscheduler.dao.repository.TenantDao; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.StorageOperator; |
||||
|
||||
import java.util.Objects; |
||||
|
||||
import org.springframework.stereotype.Component; |
||||
import org.springframework.web.multipart.MultipartFile; |
||||
|
||||
import com.google.common.io.Files; |
||||
|
||||
@Component |
||||
public class UpdateFileDtoValidator extends AbstractResourceValidator<UpdateFileDto> { |
||||
|
||||
public UpdateFileDtoValidator(StorageOperator storageOperator, TenantDao tenantDao) { |
||||
super(storageOperator, tenantDao); |
||||
} |
||||
|
||||
@Override |
||||
public void validate(UpdateFileDto updateFileDto) { |
||||
String fileAbsolutePath = updateFileDto.getFileAbsolutePath(); |
||||
User loginUser = updateFileDto.getLoginUser(); |
||||
MultipartFile file = updateFileDto.getFile(); |
||||
|
||||
if (!Objects.equals(Files.getFileExtension(file.getName()), |
||||
Files.getFileExtension(updateFileDto.getFileAbsolutePath()))) { |
||||
throw new ServiceException("file extension cannot not change"); |
||||
} |
||||
|
||||
exceptionResourceAbsolutePathInvalidated(fileAbsolutePath); |
||||
exceptionResourceNotExists(fileAbsolutePath); |
||||
exceptionResourceIsNotFile(fileAbsolutePath); |
||||
exceptionUserNoResourcePermission(loginUser, fileAbsolutePath); |
||||
exceptionFileInvalidated(file); |
||||
} |
||||
} |
@ -0,0 +1,47 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.validator.resource; |
||||
|
||||
import org.apache.dolphinscheduler.api.dto.resources.UpdateFileFromContentDto; |
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
import org.apache.dolphinscheduler.dao.repository.TenantDao; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.StorageOperator; |
||||
|
||||
import org.springframework.stereotype.Component; |
||||
|
||||
@Component |
||||
public class UpdateFileFromContentDtoValidator extends AbstractResourceValidator<UpdateFileFromContentDto> { |
||||
|
||||
public UpdateFileFromContentDtoValidator(StorageOperator storageOperator, TenantDao tenantDao) { |
||||
super(storageOperator, tenantDao); |
||||
} |
||||
|
||||
@Override |
||||
public void validate(UpdateFileFromContentDto updateFileFromContentDto) { |
||||
String fileAbsolutePath = updateFileFromContentDto.getFileAbsolutePath(); |
||||
User loginUser = updateFileFromContentDto.getLoginUser(); |
||||
String fileContent = updateFileFromContentDto.getFileContent(); |
||||
|
||||
exceptionResourceAbsolutePathInvalidated(fileAbsolutePath); |
||||
exceptionResourceNotExists(fileAbsolutePath); |
||||
exceptionResourceIsNotFile(fileAbsolutePath); |
||||
exceptionUserNoResourcePermission(loginUser, fileAbsolutePath); |
||||
exceptionFileContentCannotFetch(fileAbsolutePath); |
||||
exceptionFileContentInvalidated(fileContent); |
||||
} |
||||
} |
@ -0,0 +1,39 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.validator.resource; |
||||
|
||||
import org.apache.dolphinscheduler.api.dto.resources.UpdateFileFromContentDto; |
||||
import org.apache.dolphinscheduler.api.dto.resources.UpdateFileFromContentRequest; |
||||
import org.apache.dolphinscheduler.api.validator.ITransformer; |
||||
|
||||
import org.springframework.stereotype.Component; |
||||
|
||||
@Component |
||||
public class UpdateFileFromContentRequestTransformer |
||||
implements |
||||
ITransformer<UpdateFileFromContentRequest, UpdateFileFromContentDto> { |
||||
|
||||
@Override |
||||
public UpdateFileFromContentDto transform(UpdateFileFromContentRequest updateFileContentRequest) { |
||||
return UpdateFileFromContentDto.builder() |
||||
.loginUser(updateFileContentRequest.getLoginUser()) |
||||
.fileAbsolutePath(updateFileContentRequest.getFileAbsolutePath()) |
||||
.fileContent(updateFileContentRequest.getFileContent()) |
||||
.build(); |
||||
} |
||||
} |
@ -0,0 +1,38 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.validator.resource; |
||||
|
||||
import org.apache.dolphinscheduler.api.dto.resources.UpdateFileDto; |
||||
import org.apache.dolphinscheduler.api.dto.resources.UpdateFileRequest; |
||||
import org.apache.dolphinscheduler.api.validator.ITransformer; |
||||
|
||||
import org.springframework.stereotype.Component; |
||||
|
||||
@Component |
||||
public class UpdateFileRequestTransformer implements ITransformer<UpdateFileRequest, UpdateFileDto> { |
||||
|
||||
@Override |
||||
public UpdateFileDto transform(UpdateFileRequest updateFileRequest) { |
||||
return UpdateFileDto.builder() |
||||
.loginUser(updateFileRequest.getLoginUser()) |
||||
.fileAbsolutePath(updateFileRequest.getFileAbsolutePath()) |
||||
.file(updateFileRequest.getFile()) |
||||
.build(); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,74 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.vo; |
||||
|
||||
import org.apache.dolphinscheduler.plugin.storage.api.StorageEntity; |
||||
import org.apache.dolphinscheduler.spi.enums.ResourceType; |
||||
|
||||
import org.apache.commons.lang3.StringUtils; |
||||
|
||||
import java.io.File; |
||||
import java.util.Date; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
@Data |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class ResourceItemVO { |
||||
|
||||
// todo: remove this field, directly use fileName
|
||||
private String alias; |
||||
|
||||
// todo: use tenantName instead of userName
|
||||
private String userName; |
||||
|
||||
private String fileName; |
||||
|
||||
private String fullName; |
||||
|
||||
private boolean isDirectory; |
||||
|
||||
private ResourceType type; |
||||
|
||||
private long size; |
||||
|
||||
private Date createTime; |
||||
|
||||
private Date updateTime; |
||||
|
||||
public ResourceItemVO(StorageEntity storageEntity) { |
||||
this.isDirectory = storageEntity.isDirectory(); |
||||
this.alias = storageEntity.getFileName(); |
||||
this.fileName = storageEntity.getFileName(); |
||||
this.fullName = storageEntity.getFullName(); |
||||
this.type = storageEntity.getType(); |
||||
this.size = storageEntity.getSize(); |
||||
this.createTime = storageEntity.getCreateTime(); |
||||
this.updateTime = storageEntity.getUpdateTime(); |
||||
|
||||
if (isDirectory) { |
||||
alias = StringUtils.removeEndIgnoreCase(alias, File.separator); |
||||
fileName = StringUtils.removeEndIgnoreCase(fileName, File.separator); |
||||
fullName = StringUtils.removeEndIgnoreCase(fullName, File.separator); |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,33 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.vo.resources; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
@Data |
||||
@Builder |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class FetchFileContentResponse { |
||||
|
||||
private String content; |
||||
|
||||
} |
@ -1,657 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.service; |
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals; |
||||
import static org.mockito.ArgumentMatchers.eq; |
||||
import static org.mockito.Mockito.when; |
||||
|
||||
import org.apache.dolphinscheduler.api.dto.resources.DeleteDataTransferResponse; |
||||
import org.apache.dolphinscheduler.api.dto.resources.ResourceComponent; |
||||
import org.apache.dolphinscheduler.api.enums.Status; |
||||
import org.apache.dolphinscheduler.api.exceptions.ServiceException; |
||||
import org.apache.dolphinscheduler.api.permission.ResourcePermissionCheckService; |
||||
import org.apache.dolphinscheduler.api.service.impl.ResourcesServiceImpl; |
||||
import org.apache.dolphinscheduler.api.utils.PageInfo; |
||||
import org.apache.dolphinscheduler.api.utils.Result; |
||||
import org.apache.dolphinscheduler.common.constants.Constants; |
||||
import org.apache.dolphinscheduler.common.enums.UserType; |
||||
import org.apache.dolphinscheduler.common.utils.FileUtils; |
||||
import org.apache.dolphinscheduler.common.utils.PropertyUtils; |
||||
import org.apache.dolphinscheduler.dao.entity.Tenant; |
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
import org.apache.dolphinscheduler.dao.mapper.ProcessDefinitionMapper; |
||||
import org.apache.dolphinscheduler.dao.mapper.TenantMapper; |
||||
import org.apache.dolphinscheduler.dao.mapper.UdfFuncMapper; |
||||
import org.apache.dolphinscheduler.dao.mapper.UserMapper; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.StorageEntity; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.StorageOperate; |
||||
import org.apache.dolphinscheduler.spi.enums.ResourceType; |
||||
|
||||
import org.apache.commons.collections4.CollectionUtils; |
||||
|
||||
import java.io.IOException; |
||||
import java.nio.file.Path; |
||||
import java.nio.file.Paths; |
||||
import java.time.LocalDateTime; |
||||
import java.util.ArrayList; |
||||
import java.util.Arrays; |
||||
import java.util.Collections; |
||||
import java.util.HashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.Random; |
||||
|
||||
import org.junit.jupiter.api.AfterEach; |
||||
import org.junit.jupiter.api.Assertions; |
||||
import org.junit.jupiter.api.BeforeEach; |
||||
import org.junit.jupiter.api.Test; |
||||
import org.junit.jupiter.api.extension.ExtendWith; |
||||
import org.mockito.InjectMocks; |
||||
import org.mockito.Mock; |
||||
import org.mockito.MockedStatic; |
||||
import org.mockito.Mockito; |
||||
import org.mockito.junit.jupiter.MockitoExtension; |
||||
import org.mockito.junit.jupiter.MockitoSettings; |
||||
import org.mockito.quality.Strictness; |
||||
import org.springframework.mock.web.MockMultipartFile; |
||||
|
||||
import com.google.common.io.Files; |
||||
|
||||
/** |
||||
* resources service test |
||||
*/ |
||||
@ExtendWith(MockitoExtension.class) |
||||
@MockitoSettings(strictness = Strictness.LENIENT) |
||||
public class ResourcesServiceTest { |
||||
|
||||
private static final String basePath = "/dolphinscheduler"; |
||||
private static final String tenantCode = "123"; |
||||
private static final String tenantFileResourceDir = "/dolphinscheduler/123/resources/"; |
||||
private static final String tenantUdfResourceDir = "/dolphinscheduler/123/udfs/"; |
||||
|
||||
@InjectMocks |
||||
private ResourcesServiceImpl resourcesService; |
||||
|
||||
@Mock |
||||
private TenantMapper tenantMapper; |
||||
|
||||
@Mock |
||||
private StorageOperate storageOperate; |
||||
|
||||
@Mock |
||||
private UserMapper userMapper; |
||||
|
||||
@Mock |
||||
private UdfFuncMapper udfFunctionMapper; |
||||
|
||||
@Mock |
||||
private ProcessDefinitionMapper processDefinitionMapper; |
||||
|
||||
@Mock |
||||
private ResourcePermissionCheckService resourcePermissionCheckService; |
||||
|
||||
private MockedStatic<FileUtils> mockedStaticFileUtils; |
||||
|
||||
private MockedStatic<Files> mockedStaticFiles; |
||||
|
||||
private MockedStatic<org.apache.dolphinscheduler.api.utils.FileUtils> mockedStaticDolphinschedulerFileUtils; |
||||
|
||||
private MockedStatic<PropertyUtils> mockedStaticPropertyUtils; |
||||
|
||||
private MockedStatic<Paths> mockedStaticPaths; |
||||
|
||||
private MockedStatic<java.nio.file.Files> filesMockedStatic; |
||||
|
||||
private Exception exception; |
||||
|
||||
@BeforeEach |
||||
public void setUp() { |
||||
mockedStaticFileUtils = Mockito.mockStatic(FileUtils.class); |
||||
mockedStaticFiles = Mockito.mockStatic(Files.class); |
||||
mockedStaticDolphinschedulerFileUtils = |
||||
Mockito.mockStatic(org.apache.dolphinscheduler.api.utils.FileUtils.class); |
||||
|
||||
mockedStaticPropertyUtils = Mockito.mockStatic(PropertyUtils.class); |
||||
mockedStaticPaths = Mockito.mockStatic(Paths.class); |
||||
filesMockedStatic = Mockito.mockStatic(java.nio.file.Files.class); |
||||
} |
||||
|
||||
@AfterEach |
||||
public void after() { |
||||
mockedStaticFileUtils.close(); |
||||
mockedStaticFiles.close(); |
||||
mockedStaticDolphinschedulerFileUtils.close(); |
||||
mockedStaticPropertyUtils.close(); |
||||
mockedStaticPaths.close(); |
||||
filesMockedStatic.close(); |
||||
} |
||||
|
||||
@Test |
||||
public void testCreateResource() { |
||||
User user = new User(); |
||||
user.setId(1); |
||||
user.setUserType(UserType.GENERAL_USER); |
||||
|
||||
// CURRENT_LOGIN_USER_TENANT_NOT_EXIST
|
||||
when(userMapper.selectById(user.getId())).thenReturn(getUser()); |
||||
when(tenantMapper.queryById(1)).thenReturn(null); |
||||
ServiceException serviceException = Assertions.assertThrows(ServiceException.class, |
||||
() -> resourcesService.uploadResource(user, "ResourcesServiceTest", ResourceType.FILE, |
||||
new MockMultipartFile("test.pdf", "test.pdf", "pdf", "test".getBytes()), "/")); |
||||
assertEquals(Status.CURRENT_LOGIN_USER_TENANT_NOT_EXIST.getMsg(), serviceException.getMessage()); |
||||
|
||||
// set tenant for user
|
||||
user.setTenantId(1); |
||||
when(tenantMapper.queryById(1)).thenReturn(getTenant()); |
||||
when(storageOperate.getDir(ResourceType.ALL, tenantCode)).thenReturn(basePath); |
||||
|
||||
// ILLEGAL_RESOURCE_FILE
|
||||
String illegal_path = "/dolphinscheduler/123/../"; |
||||
serviceException = Assertions.assertThrows(ServiceException.class, |
||||
() -> { |
||||
MockMultipartFile mockMultipartFile = new MockMultipartFile("test.pdf", "".getBytes()); |
||||
resourcesService.uploadResource(user, "ResourcesServiceTest", ResourceType.FILE, |
||||
mockMultipartFile, illegal_path); |
||||
}); |
||||
assertEquals(new ServiceException(Status.ILLEGAL_RESOURCE_PATH, illegal_path), serviceException); |
||||
|
||||
// RESOURCE_FILE_IS_EMPTY
|
||||
MockMultipartFile mockMultipartFile = new MockMultipartFile("test.pdf", "".getBytes()); |
||||
Result result = resourcesService.uploadResource(user, "ResourcesServiceTest", ResourceType.FILE, |
||||
mockMultipartFile, tenantFileResourceDir); |
||||
assertEquals(Status.RESOURCE_FILE_IS_EMPTY.getMsg(), result.getMsg()); |
||||
|
||||
// RESOURCE_SUFFIX_FORBID_CHANGE
|
||||
mockMultipartFile = new MockMultipartFile("test.pdf", "test.pdf", "pdf", "test".getBytes()); |
||||
when(Files.getFileExtension("test.pdf")).thenReturn("pdf"); |
||||
when(Files.getFileExtension("ResourcesServiceTest.jar")).thenReturn("jar"); |
||||
result = resourcesService.uploadResource(user, "ResourcesServiceTest.jar", ResourceType.FILE, mockMultipartFile, |
||||
tenantFileResourceDir); |
||||
assertEquals(Status.RESOURCE_SUFFIX_FORBID_CHANGE.getMsg(), result.getMsg()); |
||||
|
||||
// UDF_RESOURCE_SUFFIX_NOT_JAR
|
||||
mockMultipartFile = |
||||
new MockMultipartFile("ResourcesServiceTest.pdf", "ResourcesServiceTest.pdf", "pdf", "test".getBytes()); |
||||
when(Files.getFileExtension("ResourcesServiceTest.pdf")).thenReturn("pdf"); |
||||
result = resourcesService.uploadResource(user, "ResourcesServiceTest.pdf", ResourceType.UDF, mockMultipartFile, |
||||
tenantUdfResourceDir); |
||||
assertEquals(Status.UDF_RESOURCE_SUFFIX_NOT_JAR.getMsg(), result.getMsg()); |
||||
|
||||
// FULL_FILE_NAME_TOO_LONG
|
||||
String tooLongFileName = getRandomStringWithLength(Constants.RESOURCE_FULL_NAME_MAX_LENGTH) + ".pdf"; |
||||
mockMultipartFile = new MockMultipartFile(tooLongFileName, tooLongFileName, "pdf", "test".getBytes()); |
||||
when(Files.getFileExtension(tooLongFileName)).thenReturn("pdf"); |
||||
|
||||
// '/databasePath/tenantCode/RESOURCE/'
|
||||
when(storageOperate.getResDir(tenantCode)).thenReturn(tenantFileResourceDir); |
||||
result = resourcesService.uploadResource(user, tooLongFileName, ResourceType.FILE, mockMultipartFile, |
||||
tenantFileResourceDir); |
||||
assertEquals(Status.RESOURCE_FULL_NAME_TOO_LONG_ERROR.getMsg(), result.getMsg()); |
||||
} |
||||
|
||||
@Test |
||||
public void testCreateDirecotry() throws IOException { |
||||
User user = new User(); |
||||
user.setId(1); |
||||
user.setUserType(UserType.GENERAL_USER); |
||||
|
||||
String fileName = "directoryTest"; |
||||
// RESOURCE_EXIST
|
||||
user.setId(1); |
||||
user.setTenantId(1); |
||||
when(tenantMapper.queryById(1)).thenReturn(getTenant()); |
||||
when(userMapper.selectById(user.getId())).thenReturn(getUser()); |
||||
when(storageOperate.getDir(ResourceType.ALL, tenantCode)).thenReturn(basePath); |
||||
when(storageOperate.getResDir(tenantCode)).thenReturn(tenantFileResourceDir); |
||||
when(storageOperate.exists(tenantFileResourceDir + fileName)).thenReturn(true); |
||||
Result result = resourcesService.createDirectory(user, fileName, ResourceType.FILE, -1, tenantFileResourceDir); |
||||
assertEquals(Status.RESOURCE_EXIST.getMsg(), result.getMsg()); |
||||
} |
||||
|
||||
@Test |
||||
public void testUpdateResource() throws Exception { |
||||
User user = new User(); |
||||
user.setId(1); |
||||
user.setUserType(UserType.GENERAL_USER); |
||||
user.setTenantId(1); |
||||
|
||||
when(userMapper.selectById(user.getId())).thenReturn(getUser()); |
||||
when(tenantMapper.queryById(1)).thenReturn(getTenant()); |
||||
when(storageOperate.getDir(ResourceType.ALL, tenantCode)).thenReturn(basePath); |
||||
when(storageOperate.getResDir(tenantCode)).thenReturn(tenantFileResourceDir); |
||||
|
||||
// TENANT_NOT_EXIST
|
||||
when(tenantMapper.queryById(Mockito.anyInt())).thenReturn(null); |
||||
Assertions.assertThrows(ServiceException.class, () -> resourcesService.updateResource(user, |
||||
"ResourcesServiceTest1.jar", "", "ResourcesServiceTest", ResourceType.UDF, null)); |
||||
|
||||
// USER_NO_OPERATION_PERM
|
||||
user.setUserType(UserType.GENERAL_USER); |
||||
// tenant who have access to resource is 123,
|
||||
Tenant tenantWNoPermission = new Tenant(); |
||||
tenantWNoPermission.setTenantCode("321"); |
||||
when(tenantMapper.queryById(1)).thenReturn(tenantWNoPermission); |
||||
when(storageOperate.getDir(ResourceType.ALL, "321")).thenReturn(basePath); |
||||
|
||||
String fileName = "ResourcesServiceTest"; |
||||
Result result = resourcesService.updateResource(user, tenantFileResourceDir + fileName, |
||||
tenantCode, fileName, ResourceType.FILE, null); |
||||
assertEquals(Status.NO_CURRENT_OPERATING_PERMISSION.getMsg(), result.getMsg()); |
||||
|
||||
// SUCCESS
|
||||
when(tenantMapper.queryById(1)).thenReturn(getTenant()); |
||||
when(storageOperate.exists(Mockito.any())).thenReturn(false); |
||||
|
||||
when(storageOperate.getDir(ResourceType.FILE, tenantCode)).thenReturn(tenantFileResourceDir); |
||||
when(storageOperate.getFileStatus(tenantFileResourceDir + fileName, |
||||
tenantFileResourceDir, tenantCode, ResourceType.FILE)) |
||||
.thenReturn(getStorageEntityResource(fileName)); |
||||
result = resourcesService.updateResource(user, tenantFileResourceDir + fileName, |
||||
tenantCode, fileName, ResourceType.FILE, null); |
||||
assertEquals(Status.SUCCESS.getMsg(), result.getMsg()); |
||||
|
||||
// Tests for udf resources.
|
||||
fileName = "ResourcesServiceTest.jar"; |
||||
when(storageOperate.getDir(ResourceType.UDF, tenantCode)).thenReturn(tenantUdfResourceDir); |
||||
when(storageOperate.exists(tenantUdfResourceDir + fileName)).thenReturn(true); |
||||
when(storageOperate.getFileStatus(tenantUdfResourceDir + fileName, tenantUdfResourceDir, tenantCode, |
||||
ResourceType.UDF)) |
||||
.thenReturn(getStorageEntityUdfResource(fileName)); |
||||
result = resourcesService.updateResource(user, tenantUdfResourceDir + fileName, |
||||
tenantCode, fileName, ResourceType.UDF, null); |
||||
assertEquals(Status.SUCCESS.getMsg(), result.getMsg()); |
||||
} |
||||
|
||||
@Test |
||||
public void testQueryResourceListPaging() throws Exception { |
||||
User loginUser = new User(); |
||||
loginUser.setId(1); |
||||
loginUser.setTenantId(1); |
||||
loginUser.setTenantCode("tenant1"); |
||||
loginUser.setUserType(UserType.ADMIN_USER); |
||||
|
||||
String fileName = "ResourcesServiceTest"; |
||||
List<StorageEntity> mockResList = new ArrayList<>(); |
||||
mockResList.add(getStorageEntityResource(fileName)); |
||||
List<User> mockUserList = new ArrayList<>(); |
||||
mockUserList.add(getUser()); |
||||
when(userMapper.selectList(null)).thenReturn(mockUserList); |
||||
when(userMapper.selectById(getUser().getId())).thenReturn(getUser()); |
||||
when(tenantMapper.queryById(getUser().getTenantId())).thenReturn(getTenant()); |
||||
when(storageOperate.getResDir(tenantCode)).thenReturn(tenantFileResourceDir); |
||||
when(storageOperate.listFilesStatus(tenantFileResourceDir, tenantFileResourceDir, |
||||
tenantCode, ResourceType.FILE)).thenReturn(mockResList); |
||||
|
||||
Result result = resourcesService.queryResourceListPaging(loginUser, "", "", ResourceType.FILE, "Test", 1, 10); |
||||
assertEquals(Status.SUCCESS.getCode(), (int) result.getCode()); |
||||
PageInfo pageInfo = (PageInfo) result.getData(); |
||||
Assertions.assertTrue(CollectionUtils.isNotEmpty(pageInfo.getTotalList())); |
||||
|
||||
} |
||||
|
||||
@Test |
||||
public void testQueryResourceList() { |
||||
User loginUser = getUser(); |
||||
String fileName = "ResourcesServiceTest"; |
||||
|
||||
when(userMapper.selectList(null)).thenReturn(Collections.singletonList(loginUser)); |
||||
when(userMapper.selectById(loginUser.getId())).thenReturn(loginUser); |
||||
when(tenantMapper.queryById(Mockito.anyInt())).thenReturn(getTenant()); |
||||
when(storageOperate.getDir(ResourceType.ALL, tenantCode)).thenReturn(basePath); |
||||
when(storageOperate.getDir(ResourceType.FILE, tenantCode)).thenReturn(tenantFileResourceDir); |
||||
when(storageOperate.getResDir(tenantCode)).thenReturn(tenantFileResourceDir); |
||||
when(storageOperate.listFilesStatusRecursively(tenantFileResourceDir, |
||||
tenantFileResourceDir, tenantCode, ResourceType.FILE)) |
||||
.thenReturn(Collections.singletonList(getStorageEntityResource(fileName))); |
||||
Map<String, Object> result = |
||||
resourcesService.queryResourceList(loginUser, ResourceType.FILE, tenantFileResourceDir); |
||||
assertEquals(Status.SUCCESS, result.get(Constants.STATUS)); |
||||
List<ResourceComponent> resourceList = (List<ResourceComponent>) result.get(Constants.DATA_LIST); |
||||
Assertions.assertTrue(CollectionUtils.isNotEmpty(resourceList)); |
||||
|
||||
// test udf
|
||||
when(storageOperate.getDir(ResourceType.UDF, tenantCode)).thenReturn(tenantUdfResourceDir); |
||||
when(storageOperate.getUdfDir(tenantCode)).thenReturn(tenantUdfResourceDir); |
||||
when(storageOperate.listFilesStatusRecursively(tenantUdfResourceDir, tenantUdfResourceDir, |
||||
tenantCode, ResourceType.UDF)).thenReturn(Arrays.asList(getStorageEntityUdfResource("test.jar"))); |
||||
loginUser.setUserType(UserType.GENERAL_USER); |
||||
result = resourcesService.queryResourceList(loginUser, ResourceType.UDF, tenantUdfResourceDir); |
||||
assertEquals(Status.SUCCESS, result.get(Constants.STATUS)); |
||||
resourceList = (List<ResourceComponent>) result.get(Constants.DATA_LIST); |
||||
Assertions.assertTrue(CollectionUtils.isNotEmpty(resourceList)); |
||||
} |
||||
|
||||
@Test |
||||
public void testDelete() throws Exception { |
||||
User loginUser = new User(); |
||||
loginUser.setId(0); |
||||
loginUser.setUserType(UserType.GENERAL_USER); |
||||
|
||||
// TENANT_NOT_EXIST
|
||||
loginUser.setUserType(UserType.ADMIN_USER); |
||||
loginUser.setTenantId(2); |
||||
when(userMapper.selectById(loginUser.getId())).thenReturn(loginUser); |
||||
Assertions.assertThrows(ServiceException.class, () -> resourcesService.delete(loginUser, "", "")); |
||||
|
||||
// RESOURCE_NOT_EXIST
|
||||
String fileName = "ResourcesServiceTest"; |
||||
when(tenantMapper.queryById(Mockito.anyInt())).thenReturn(getTenant()); |
||||
when(storageOperate.getDir(ResourceType.ALL, tenantCode)).thenReturn(basePath); |
||||
when(storageOperate.getResDir(getTenant().getTenantCode())).thenReturn(tenantFileResourceDir); |
||||
when(storageOperate.getFileStatus(tenantFileResourceDir + fileName, tenantFileResourceDir, tenantCode, null)) |
||||
.thenReturn(getStorageEntityResource(fileName)); |
||||
Result result = resourcesService.delete(loginUser, tenantFileResourceDir + "ResNotExist", tenantCode); |
||||
assertEquals(Status.RESOURCE_NOT_EXIST.getMsg(), result.getMsg()); |
||||
|
||||
// SUCCESS
|
||||
loginUser.setTenantId(1); |
||||
result = resourcesService.delete(loginUser, tenantFileResourceDir + fileName, tenantCode); |
||||
assertEquals(Status.SUCCESS.getMsg(), result.getMsg()); |
||||
} |
||||
|
||||
@Test |
||||
public void testVerifyResourceName() throws IOException { |
||||
User user = new User(); |
||||
user.setId(1); |
||||
user.setUserType(UserType.GENERAL_USER); |
||||
|
||||
String fileName = "ResourcesServiceTest"; |
||||
when(storageOperate.exists(tenantFileResourceDir + fileName)).thenReturn(true); |
||||
|
||||
Result result = resourcesService.verifyResourceName(tenantFileResourceDir + fileName, ResourceType.FILE, user); |
||||
assertEquals(Status.RESOURCE_EXIST.getMsg(), result.getMsg()); |
||||
|
||||
// RESOURCE_FILE_EXIST
|
||||
result = resourcesService.verifyResourceName(tenantFileResourceDir + fileName, ResourceType.FILE, user); |
||||
Assertions.assertTrue(Status.RESOURCE_EXIST.getCode() == result.getCode()); |
||||
|
||||
// SUCCESS
|
||||
result = resourcesService.verifyResourceName("test2", ResourceType.FILE, user); |
||||
assertEquals(Status.SUCCESS.getMsg(), result.getMsg()); |
||||
} |
||||
|
||||
@Test |
||||
public void testReadResource() throws IOException { |
||||
// RESOURCE_NOT_EXIST
|
||||
when(userMapper.selectById(getUser().getId())).thenReturn(getUser()); |
||||
when(tenantMapper.queryById(getUser().getTenantId())).thenReturn(getTenant()); |
||||
Result result = resourcesService.readResource(getUser(), "", "", 1, 10); |
||||
assertEquals(Status.RESOURCE_FILE_NOT_EXIST.getCode(), (int) result.getCode()); |
||||
|
||||
// RESOURCE_SUFFIX_NOT_SUPPORT_VIEW
|
||||
when(FileUtils.getResourceViewSuffixes()).thenReturn("class"); |
||||
result = resourcesService.readResource(getUser(), "", "", 1, 10); |
||||
assertEquals(Status.RESOURCE_SUFFIX_NOT_SUPPORT_VIEW.getMsg(), result.getMsg()); |
||||
|
||||
// USER_NOT_EXIST
|
||||
when(userMapper.selectById(getUser().getId())).thenReturn(null); |
||||
when(FileUtils.getResourceViewSuffixes()).thenReturn("jar"); |
||||
when(Files.getFileExtension("ResourcesServiceTest.jar")).thenReturn("jar"); |
||||
result = resourcesService.readResource(getUser(), "", "", 1, 10); |
||||
assertEquals(Status.USER_NOT_EXIST.getCode(), (int) result.getCode()); |
||||
|
||||
// TENANT_NOT_EXIST
|
||||
when(userMapper.selectById(getUser().getId())).thenReturn(getUser()); |
||||
when(tenantMapper.queryById(getUser().getTenantId())).thenReturn(null); |
||||
Assertions.assertThrows(ServiceException.class, () -> resourcesService.readResource(getUser(), "", "", 1, 10)); |
||||
|
||||
// SUCCESS
|
||||
when(FileUtils.getResourceViewSuffixes()).thenReturn("jar,sh"); |
||||
when(storageOperate.getDir(ResourceType.ALL, tenantCode)).thenReturn(basePath); |
||||
when(storageOperate.getResDir(getTenant().getTenantCode())).thenReturn(tenantFileResourceDir); |
||||
when(userMapper.selectById(getUser().getId())).thenReturn(getUser()); |
||||
when(tenantMapper.queryById(getUser().getTenantId())).thenReturn(getTenant()); |
||||
when(storageOperate.exists(Mockito.any())).thenReturn(true); |
||||
when(storageOperate.vimFile(Mockito.any(), Mockito.any(), eq(1), eq(10))).thenReturn(getContent()); |
||||
when(Files.getFileExtension("/dolphinscheduler/123/resources/test.jar")).thenReturn("jar"); |
||||
result = resourcesService.readResource(getUser(), "/dolphinscheduler/123/resources/test.jar", tenantCode, 1, |
||||
10); |
||||
assertEquals(Status.SUCCESS.getMsg(), result.getMsg()); |
||||
} |
||||
|
||||
@Test |
||||
public void testCreateOrUpdateResource() throws Exception { |
||||
User user = getUser(); |
||||
when(userMapper.queryByUserNameAccurately(user.getUserName())).thenReturn(getUser()); |
||||
|
||||
// RESOURCE_SUFFIX_NOT_SUPPORT_VIEW
|
||||
exception = Assertions.assertThrows(IllegalArgumentException.class, |
||||
() -> resourcesService.createOrUpdateResource(user.getUserName(), "filename", "my-content")); |
||||
Assertions.assertTrue( |
||||
exception.getMessage().contains("Not allow create or update resources without extension name")); |
||||
|
||||
// SUCCESS
|
||||
String fileName = "ResourcesServiceTest"; |
||||
when(storageOperate.getResDir(user.getTenantCode())).thenReturn(tenantFileResourceDir); |
||||
when(FileUtils.getUploadFilename(Mockito.anyString(), Mockito.anyString())).thenReturn("test"); |
||||
when(FileUtils.writeContent2File(Mockito.anyString(), Mockito.anyString())).thenReturn(true); |
||||
when(storageOperate.getFileStatus(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.any())) |
||||
.thenReturn(getStorageEntityResource(fileName)); |
||||
StorageEntity storageEntity = |
||||
resourcesService.createOrUpdateResource(user.getUserName(), "filename.txt", "my-content"); |
||||
Assertions.assertNotNull(storageEntity); |
||||
assertEquals(tenantFileResourceDir + fileName, storageEntity.getFullName()); |
||||
} |
||||
|
||||
@Test |
||||
public void testUpdateResourceContent() throws Exception { |
||||
// RESOURCE_PATH_ILLEGAL
|
||||
when(userMapper.selectById(getUser().getId())).thenReturn(getUser()); |
||||
when(tenantMapper.queryById(1)).thenReturn(getTenant()); |
||||
when(storageOperate.getResDir(Mockito.anyString())).thenReturn("/tmp"); |
||||
|
||||
String fileName = "ResourcesServiceTest.jar"; |
||||
ServiceException serviceException = |
||||
Assertions.assertThrows(ServiceException.class, () -> resourcesService.updateResourceContent(getUser(), |
||||
tenantFileResourceDir + fileName, tenantCode, "content")); |
||||
assertEquals(new ServiceException(Status.ILLEGAL_RESOURCE_PATH, tenantFileResourceDir + fileName), |
||||
serviceException); |
||||
|
||||
// RESOURCE_NOT_EXIST
|
||||
when(storageOperate.getDir(ResourceType.ALL, tenantCode)).thenReturn(basePath); |
||||
when(storageOperate.getResDir(Mockito.anyString())).thenReturn(tenantFileResourceDir); |
||||
when(storageOperate.getFileStatus(tenantFileResourceDir + fileName, "", tenantCode, ResourceType.FILE)) |
||||
.thenReturn(null); |
||||
Result result = resourcesService.updateResourceContent(getUser(), tenantFileResourceDir + fileName, tenantCode, |
||||
"content"); |
||||
assertEquals(Status.RESOURCE_NOT_EXIST.getMsg(), result.getMsg()); |
||||
|
||||
// RESOURCE_SUFFIX_NOT_SUPPORT_VIEW
|
||||
when(FileUtils.getResourceViewSuffixes()).thenReturn("class"); |
||||
when(storageOperate.getFileStatus(tenantFileResourceDir, "", tenantCode, ResourceType.FILE)) |
||||
.thenReturn(getStorageEntityResource(fileName)); |
||||
|
||||
result = resourcesService.updateResourceContent(getUser(), tenantFileResourceDir, tenantCode, |
||||
"content"); |
||||
assertEquals(Status.RESOURCE_SUFFIX_NOT_SUPPORT_VIEW.getMsg(), result.getMsg()); |
||||
|
||||
// USER_NOT_EXIST
|
||||
when(userMapper.selectById(getUser().getId())).thenReturn(null); |
||||
result = resourcesService.updateResourceContent(getUser(), tenantFileResourceDir + "123.class", |
||||
tenantCode, |
||||
"content"); |
||||
Assertions.assertTrue(Status.USER_NOT_EXIST.getCode() == result.getCode()); |
||||
|
||||
// TENANT_NOT_EXIST
|
||||
when(userMapper.selectById(getUser().getId())).thenReturn(getUser()); |
||||
when(tenantMapper.queryById(1)).thenReturn(null); |
||||
Assertions.assertThrows(ServiceException.class, () -> resourcesService.updateResourceContent(getUser(), |
||||
tenantFileResourceDir + fileName, tenantCode, "content")); |
||||
|
||||
// SUCCESS
|
||||
when(storageOperate.getFileStatus(tenantFileResourceDir + fileName, "", tenantCode, |
||||
ResourceType.FILE)).thenReturn(getStorageEntityResource(fileName)); |
||||
|
||||
when(Files.getFileExtension(Mockito.anyString())).thenReturn("jar"); |
||||
when(FileUtils.getResourceViewSuffixes()).thenReturn("jar"); |
||||
when(userMapper.selectById(getUser().getId())).thenReturn(getUser()); |
||||
when(tenantMapper.queryById(1)).thenReturn(getTenant()); |
||||
when(FileUtils.getUploadFilename(Mockito.anyString(), Mockito.anyString())).thenReturn("test"); |
||||
when(FileUtils.writeContent2File(Mockito.anyString(), Mockito.anyString())).thenReturn(true); |
||||
result = resourcesService.updateResourceContent(getUser(), |
||||
tenantFileResourceDir + fileName, tenantCode, "content"); |
||||
assertEquals(Status.SUCCESS.getMsg(), result.getMsg()); |
||||
} |
||||
|
||||
@Test |
||||
public void testDownloadResource() throws IOException { |
||||
when(tenantMapper.queryById(1)).thenReturn(getTenant()); |
||||
when(userMapper.selectById(1)).thenReturn(getUser()); |
||||
org.springframework.core.io.Resource resourceMock = Mockito.mock(org.springframework.core.io.Resource.class); |
||||
Path path = Mockito.mock(Path.class); |
||||
when(Paths.get(Mockito.any())).thenReturn(path); |
||||
when(java.nio.file.Files.size(Mockito.any())).thenReturn(1L); |
||||
// resource null
|
||||
org.springframework.core.io.Resource resource = resourcesService.downloadResource(getUser(), ""); |
||||
Assertions.assertNull(resource); |
||||
|
||||
when(org.apache.dolphinscheduler.api.utils.FileUtils.file2Resource(Mockito.any())).thenReturn(resourceMock); |
||||
resource = resourcesService.downloadResource(getUser(), ""); |
||||
Assertions.assertNotNull(resource); |
||||
} |
||||
|
||||
@Test |
||||
public void testDeleteDataTransferData() throws Exception { |
||||
User user = getUser(); |
||||
when(userMapper.selectById(user.getId())).thenReturn(getUser()); |
||||
when(tenantMapper.queryById(user.getTenantId())).thenReturn(getTenant()); |
||||
|
||||
StorageEntity storageEntity1 = Mockito.mock(StorageEntity.class); |
||||
StorageEntity storageEntity2 = Mockito.mock(StorageEntity.class); |
||||
StorageEntity storageEntity3 = Mockito.mock(StorageEntity.class); |
||||
StorageEntity storageEntity4 = Mockito.mock(StorageEntity.class); |
||||
StorageEntity storageEntity5 = Mockito.mock(StorageEntity.class); |
||||
|
||||
when(storageEntity1.getFullName()).thenReturn("DATA_TRANSFER/20220101"); |
||||
when(storageEntity2.getFullName()).thenReturn("DATA_TRANSFER/20220102"); |
||||
when(storageEntity3.getFullName()).thenReturn("DATA_TRANSFER/20220103"); |
||||
when(storageEntity4.getFullName()).thenReturn("DATA_TRANSFER/20220104"); |
||||
when(storageEntity5.getFullName()).thenReturn("DATA_TRANSFER/20220105"); |
||||
|
||||
List<StorageEntity> storageEntityList = new ArrayList<>(); |
||||
storageEntityList.add(storageEntity1); |
||||
storageEntityList.add(storageEntity2); |
||||
storageEntityList.add(storageEntity3); |
||||
storageEntityList.add(storageEntity4); |
||||
storageEntityList.add(storageEntity5); |
||||
|
||||
when(storageOperate.listFilesStatus(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) |
||||
.thenReturn(storageEntityList); |
||||
|
||||
LocalDateTime localDateTime = LocalDateTime.of(2022, 1, 5, 0, 0, 0); |
||||
try (MockedStatic<LocalDateTime> mockHook = Mockito.mockStatic(LocalDateTime.class)) { |
||||
mockHook.when(LocalDateTime::now).thenReturn(localDateTime); |
||||
DeleteDataTransferResponse response = resourcesService.deleteDataTransferData(user, 3); |
||||
|
||||
assertEquals(response.getSuccessList().size(), 2); |
||||
assertEquals(response.getSuccessList().get(0), "DATA_TRANSFER/20220101"); |
||||
assertEquals(response.getSuccessList().get(1), "DATA_TRANSFER/20220102"); |
||||
} |
||||
|
||||
try (MockedStatic<LocalDateTime> mockHook = Mockito.mockStatic(LocalDateTime.class)) { |
||||
mockHook.when(LocalDateTime::now).thenReturn(localDateTime); |
||||
DeleteDataTransferResponse response = resourcesService.deleteDataTransferData(user, 0); |
||||
assertEquals(response.getSuccessList().size(), 5); |
||||
} |
||||
|
||||
} |
||||
|
||||
@Test |
||||
public void testCatFile() throws IOException { |
||||
// SUCCESS
|
||||
List<String> list = storageOperate.vimFile(Mockito.any(), Mockito.anyString(), eq(1), eq(10)); |
||||
Assertions.assertNotNull(list); |
||||
} |
||||
|
||||
@Test |
||||
void testQueryBaseDir() throws Exception { |
||||
User user = getUser(); |
||||
String fileName = "ResourcesServiceTest.jar"; |
||||
when(userMapper.selectById(user.getId())).thenReturn(getUser()); |
||||
when(tenantMapper.queryById(user.getTenantId())).thenReturn(getTenant()); |
||||
when(storageOperate.getDir(ResourceType.FILE, tenantCode)).thenReturn(tenantFileResourceDir); |
||||
when(storageOperate.getFileStatus(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), |
||||
Mockito.any())).thenReturn(getStorageEntityResource(fileName)); |
||||
Result<Object> result = resourcesService.queryResourceBaseDir(user, ResourceType.FILE); |
||||
assertEquals(Status.SUCCESS.getMsg(), result.getMsg()); |
||||
} |
||||
|
||||
private Tenant getTenant() { |
||||
Tenant tenant = new Tenant(); |
||||
tenant.setTenantCode(tenantCode); |
||||
return tenant; |
||||
} |
||||
|
||||
private User getUser() { |
||||
User user = new User(); |
||||
user.setId(1); |
||||
user.setUserType(UserType.GENERAL_USER); |
||||
user.setTenantId(1); |
||||
user.setTenantCode(tenantCode); |
||||
return user; |
||||
} |
||||
|
||||
private StorageEntity getStorageEntityResource(String fileName) { |
||||
StorageEntity entity = new StorageEntity(); |
||||
entity.setAlias(fileName); |
||||
entity.setFileName(fileName); |
||||
entity.setDirectory(false); |
||||
entity.setUserName(tenantCode); |
||||
entity.setType(ResourceType.FILE); |
||||
entity.setFullName(tenantFileResourceDir + fileName); |
||||
return entity; |
||||
} |
||||
|
||||
private StorageEntity getStorageEntityUdfResource(String fileName) { |
||||
StorageEntity entity = new StorageEntity(); |
||||
entity.setAlias(fileName); |
||||
entity.setFileName(fileName); |
||||
entity.setDirectory(false); |
||||
entity.setUserName(tenantCode); |
||||
entity.setType(ResourceType.UDF); |
||||
entity.setFullName(tenantUdfResourceDir + fileName); |
||||
|
||||
return entity; |
||||
} |
||||
|
||||
private List<String> getContent() { |
||||
List<String> contentList = new ArrayList<>(); |
||||
contentList.add("test"); |
||||
return contentList; |
||||
} |
||||
|
||||
private List<Map<String, Object>> getResources() { |
||||
List<Map<String, Object>> resources = new ArrayList<>(); |
||||
Map<String, Object> resource = new HashMap<>(); |
||||
resource.put("id", 1); |
||||
resource.put("resource_ids", "1"); |
||||
resources.add(resource); |
||||
return resources; |
||||
} |
||||
|
||||
private static String getRandomStringWithLength(int length) { |
||||
Random r = new Random(); |
||||
StringBuilder sb = new StringBuilder(); |
||||
while (sb.length() < length) { |
||||
char c = (char) (r.nextInt(26) + 'a'); |
||||
sb.append(c); |
||||
} |
||||
return sb.toString(); |
||||
} |
||||
} |
@ -0,0 +1,136 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.validator.resource; |
||||
|
||||
import static org.apache.dolphinscheduler.api.AssertionsHelper.assertThrowServiceException; |
||||
import static org.mockito.Mockito.when; |
||||
|
||||
import org.apache.dolphinscheduler.api.dto.resources.CreateDirectoryDto; |
||||
import org.apache.dolphinscheduler.common.enums.UserType; |
||||
import org.apache.dolphinscheduler.dao.entity.Tenant; |
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
import org.apache.dolphinscheduler.dao.repository.TenantDao; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.ResourceMetadata; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.StorageOperator; |
||||
|
||||
import java.util.Locale; |
||||
import java.util.Optional; |
||||
|
||||
import org.junit.jupiter.api.BeforeEach; |
||||
import org.junit.jupiter.api.Test; |
||||
import org.junit.jupiter.api.extension.ExtendWith; |
||||
import org.mockito.InjectMocks; |
||||
import org.mockito.Mock; |
||||
import org.mockito.junit.jupiter.MockitoExtension; |
||||
import org.springframework.context.i18n.LocaleContextHolder; |
||||
|
||||
@ExtendWith(MockitoExtension.class) |
||||
class CreateDirectoryDtoValidatorTest { |
||||
|
||||
@Mock |
||||
private StorageOperator storageOperator; |
||||
|
||||
@Mock |
||||
private TenantDao tenantDao; |
||||
|
||||
@InjectMocks |
||||
private CreateDirectoryDtoValidator createDirectoryDtoValidator; |
||||
|
||||
private static final String BASE_DIRECTORY = "/tmp/dolphinscheduler"; |
||||
|
||||
private User loginUser; |
||||
|
||||
@BeforeEach |
||||
public void setup() { |
||||
when(storageOperator.getStorageBaseDirectory()).thenReturn(BASE_DIRECTORY); |
||||
loginUser = new User(); |
||||
loginUser.setTenantId(1); |
||||
LocaleContextHolder.setLocale(Locale.ENGLISH); |
||||
} |
||||
|
||||
@Test |
||||
void testValidate_notUnderBaseDirectory() { |
||||
CreateDirectoryDto createDirectoryDto = CreateDirectoryDto.builder() |
||||
.loginUser(loginUser) |
||||
.directoryAbsolutePath("/tmp") |
||||
.build(); |
||||
assertThrowServiceException( |
||||
"Internal Server Error: Invalidated resource path: /tmp", |
||||
() -> createDirectoryDtoValidator.validate(createDirectoryDto)); |
||||
} |
||||
|
||||
@Test |
||||
public void testValidate_directoryPathContainsIllegalSymbolic() { |
||||
CreateDirectoryDto createDirectoryDto = CreateDirectoryDto.builder() |
||||
.loginUser(loginUser) |
||||
.directoryAbsolutePath("/tmp/dolphinscheduler/default/resources/..") |
||||
.build(); |
||||
assertThrowServiceException( |
||||
"Internal Server Error: Invalidated resource path: /tmp/dolphinscheduler/default/resources/..", |
||||
() -> createDirectoryDtoValidator.validate(createDirectoryDto)); |
||||
} |
||||
|
||||
@Test |
||||
public void testValidate_directoryExist() { |
||||
CreateDirectoryDto createDirectoryDto = CreateDirectoryDto.builder() |
||||
.loginUser(loginUser) |
||||
.directoryAbsolutePath("/tmp/dolphinscheduler/default/resources/demo") |
||||
.build(); |
||||
when(storageOperator.exists(createDirectoryDto.getDirectoryAbsolutePath())).thenReturn(true); |
||||
assertThrowServiceException( |
||||
"Internal Server Error: The resource is already exist: /tmp/dolphinscheduler/default/resources/demo", |
||||
() -> createDirectoryDtoValidator.validate(createDirectoryDto)); |
||||
} |
||||
|
||||
@Test |
||||
public void testValidate_NoPermission() { |
||||
Tenant tenant = new Tenant(); |
||||
tenant.setTenantCode("test"); |
||||
when(tenantDao.queryOptionalById(loginUser.getTenantId())).thenReturn(Optional.of(tenant)); |
||||
|
||||
CreateDirectoryDto createDirectoryDto = CreateDirectoryDto.builder() |
||||
.loginUser(loginUser) |
||||
.directoryAbsolutePath("/tmp/dolphinscheduler/default/resources/demo") |
||||
.build(); |
||||
when(storageOperator.getResourceMetaData(createDirectoryDto.getDirectoryAbsolutePath())) |
||||
.thenReturn(ResourceMetadata.builder() |
||||
.resourceAbsolutePath(createDirectoryDto.getDirectoryAbsolutePath()) |
||||
.resourceBaseDirectory(BASE_DIRECTORY) |
||||
.resourceRelativePath("demo") |
||||
.isDirectory(true) |
||||
.tenant("default") |
||||
.build()); |
||||
when(storageOperator.exists(createDirectoryDto.getDirectoryAbsolutePath())).thenReturn(false); |
||||
assertThrowServiceException( |
||||
"Internal Server Error: The user's tenant is test have no permission to access the resource: /tmp/dolphinscheduler/default/resources/demo", |
||||
() -> createDirectoryDtoValidator.validate(createDirectoryDto)); |
||||
} |
||||
|
||||
@Test |
||||
public void testValidate_pathNotDirectory() { |
||||
CreateDirectoryDto createDirectoryDto = CreateDirectoryDto.builder() |
||||
.loginUser(loginUser) |
||||
.directoryAbsolutePath("/tmp/dolphinscheduler/default/resources/demo.sql") |
||||
.build(); |
||||
loginUser.setUserType(UserType.ADMIN_USER); |
||||
assertThrowServiceException( |
||||
"Internal Server Error: The path is not a directory: /tmp/dolphinscheduler/default/resources/demo.sql", |
||||
() -> createDirectoryDtoValidator.validate(createDirectoryDto)); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,188 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.validator.resource; |
||||
|
||||
import static org.apache.dolphinscheduler.api.AssertionsHelper.assertDoesNotThrow; |
||||
import static org.apache.dolphinscheduler.api.AssertionsHelper.assertThrowServiceException; |
||||
import static org.mockito.Mockito.when; |
||||
|
||||
import org.apache.dolphinscheduler.api.dto.resources.CreateFileFromContentDto; |
||||
import org.apache.dolphinscheduler.dao.entity.Tenant; |
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
import org.apache.dolphinscheduler.dao.repository.TenantDao; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.ResourceMetadata; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.StorageOperator; |
||||
|
||||
import java.util.Locale; |
||||
import java.util.Optional; |
||||
|
||||
import org.junit.jupiter.api.BeforeEach; |
||||
import org.junit.jupiter.api.Test; |
||||
import org.junit.jupiter.api.extension.ExtendWith; |
||||
import org.mockito.InjectMocks; |
||||
import org.mockito.Mock; |
||||
import org.mockito.junit.jupiter.MockitoExtension; |
||||
import org.springframework.context.i18n.LocaleContextHolder; |
||||
|
||||
@ExtendWith(MockitoExtension.class) |
||||
class CreateFileFromContentDtoValidatorTest { |
||||
|
||||
@Mock |
||||
private StorageOperator storageOperator; |
||||
|
||||
@Mock |
||||
private TenantDao tenantDao; |
||||
|
||||
@InjectMocks |
||||
private CreateFileFromContentDtoValidator createFileFromContentDtoValidator; |
||||
|
||||
private static final String BASE_DIRECTORY = "/tmp/dolphinscheduler"; |
||||
|
||||
private User loginUser; |
||||
|
||||
@BeforeEach |
||||
public void setup() { |
||||
when(storageOperator.getStorageBaseDirectory()).thenReturn(BASE_DIRECTORY); |
||||
loginUser = new User(); |
||||
loginUser.setTenantId(1); |
||||
LocaleContextHolder.setLocale(Locale.ENGLISH); |
||||
} |
||||
|
||||
@Test |
||||
void testValidate_notUnderBaseDirectory() { |
||||
CreateFileFromContentDto createFileFromContentDto = CreateFileFromContentDto.builder() |
||||
.loginUser(loginUser) |
||||
.fileAbsolutePath("/tmp") |
||||
.fileContent("select * from t") |
||||
.build(); |
||||
assertThrowServiceException( |
||||
"Internal Server Error: Invalidated resource path: /tmp", |
||||
() -> createFileFromContentDtoValidator.validate(createFileFromContentDto)); |
||||
|
||||
} |
||||
|
||||
@Test |
||||
public void testValidate_filePathContainsIllegalSymbolic() { |
||||
CreateFileFromContentDto renameDirectoryDto = CreateFileFromContentDto.builder() |
||||
.loginUser(loginUser) |
||||
.fileAbsolutePath("/tmp/dolphinscheduler/default/resources/..") |
||||
.fileContent("select * from t") |
||||
.build(); |
||||
assertThrowServiceException( |
||||
"Internal Server Error: Invalidated resource path: /tmp/dolphinscheduler/default/resources/..", |
||||
() -> createFileFromContentDtoValidator.validate(renameDirectoryDto)); |
||||
} |
||||
|
||||
@Test |
||||
public void testValidate_IsNotFile() { |
||||
CreateFileFromContentDto createFileFromContentDto = CreateFileFromContentDto.builder() |
||||
.loginUser(loginUser) |
||||
.fileAbsolutePath("/tmp/dolphinscheduler/default/resources/a") |
||||
.fileContent("select * from t") |
||||
.build(); |
||||
assertThrowServiceException( |
||||
"Internal Server Error: The path is not a file: /tmp/dolphinscheduler/default/resources/a", |
||||
() -> createFileFromContentDtoValidator.validate(createFileFromContentDto)); |
||||
} |
||||
|
||||
@Test |
||||
public void testValidate_fileAlreadyExist() { |
||||
CreateFileFromContentDto createFileFromContentDto = CreateFileFromContentDto.builder() |
||||
.loginUser(loginUser) |
||||
.fileAbsolutePath("/tmp/dolphinscheduler/default/resources/a.sql") |
||||
.fileContent("select * from t") |
||||
.build(); |
||||
when(storageOperator.exists(createFileFromContentDto.getFileAbsolutePath())).thenReturn(true); |
||||
assertThrowServiceException( |
||||
"Internal Server Error: The resource is already exist: /tmp/dolphinscheduler/default/resources/a.sql", |
||||
() -> createFileFromContentDtoValidator.validate(createFileFromContentDto)); |
||||
} |
||||
|
||||
@Test |
||||
public void testValidate_fileNoPermission() { |
||||
Tenant tenant = new Tenant(); |
||||
tenant.setTenantCode("test"); |
||||
when(tenantDao.queryOptionalById(loginUser.getTenantId())).thenReturn(Optional.of(tenant)); |
||||
|
||||
CreateFileFromContentDto createFileFromContentDto = CreateFileFromContentDto.builder() |
||||
.loginUser(loginUser) |
||||
.fileAbsolutePath("/tmp/dolphinscheduler/default/resources/a.sql") |
||||
.fileContent("select * from t") |
||||
.build(); |
||||
when(storageOperator.exists(createFileFromContentDto.getFileAbsolutePath())).thenReturn(false); |
||||
when(storageOperator.getResourceMetaData(createFileFromContentDto.getFileAbsolutePath())) |
||||
.thenReturn(ResourceMetadata.builder() |
||||
.resourceAbsolutePath(createFileFromContentDto.getFileAbsolutePath()) |
||||
.resourceBaseDirectory(BASE_DIRECTORY) |
||||
.resourceRelativePath("a.sql") |
||||
.isDirectory(false) |
||||
.tenant("default") |
||||
.build()); |
||||
assertThrowServiceException( |
||||
"Internal Server Error: The user's tenant is test have no permission to access the resource: /tmp/dolphinscheduler/default/resources/a.sql", |
||||
() -> createFileFromContentDtoValidator.validate(createFileFromContentDto)); |
||||
} |
||||
|
||||
@Test |
||||
public void testValidate_contentIsInvalidated() { |
||||
Tenant tenant = new Tenant(); |
||||
tenant.setTenantCode("default"); |
||||
when(tenantDao.queryOptionalById(loginUser.getTenantId())).thenReturn(Optional.of(tenant)); |
||||
|
||||
CreateFileFromContentDto createFileFromContentDto = CreateFileFromContentDto.builder() |
||||
.loginUser(loginUser) |
||||
.fileAbsolutePath("/tmp/dolphinscheduler/default/resources/a.sql") |
||||
.fileContent("") |
||||
.build(); |
||||
when(storageOperator.exists(createFileFromContentDto.getFileAbsolutePath())).thenReturn(false); |
||||
when(storageOperator.getResourceMetaData(createFileFromContentDto.getFileAbsolutePath())) |
||||
.thenReturn(ResourceMetadata.builder() |
||||
.resourceAbsolutePath(createFileFromContentDto.getFileAbsolutePath()) |
||||
.resourceBaseDirectory(BASE_DIRECTORY) |
||||
.resourceRelativePath("a.sql") |
||||
.isDirectory(false) |
||||
.tenant("default") |
||||
.build()); |
||||
assertThrowServiceException( |
||||
"Internal Server Error: The file content is null", |
||||
() -> createFileFromContentDtoValidator.validate(createFileFromContentDto)); |
||||
} |
||||
|
||||
@Test |
||||
public void testValidate() { |
||||
Tenant tenant = new Tenant(); |
||||
tenant.setTenantCode("default"); |
||||
when(tenantDao.queryOptionalById(loginUser.getTenantId())).thenReturn(Optional.of(tenant)); |
||||
|
||||
CreateFileFromContentDto createFileFromContentDto = CreateFileFromContentDto.builder() |
||||
.loginUser(loginUser) |
||||
.fileAbsolutePath("/tmp/dolphinscheduler/default/resources/a.sql") |
||||
.fileContent("select * from t") |
||||
.build(); |
||||
when(storageOperator.exists(createFileFromContentDto.getFileAbsolutePath())).thenReturn(false); |
||||
when(storageOperator.getResourceMetaData(createFileFromContentDto.getFileAbsolutePath())) |
||||
.thenReturn(ResourceMetadata.builder() |
||||
.resourceAbsolutePath(createFileFromContentDto.getFileAbsolutePath()) |
||||
.resourceBaseDirectory(BASE_DIRECTORY) |
||||
.resourceRelativePath("a.sql") |
||||
.isDirectory(false) |
||||
.tenant("default") |
||||
.build()); |
||||
assertDoesNotThrow(() -> createFileFromContentDtoValidator.validate(createFileFromContentDto)); |
||||
} |
||||
} |
@ -0,0 +1,197 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.apache.dolphinscheduler.api.validator.resource; |
||||
|
||||
import static org.apache.dolphinscheduler.api.AssertionsHelper.assertThrowServiceException; |
||||
import static org.mockito.Mockito.when; |
||||
|
||||
import org.apache.dolphinscheduler.api.AssertionsHelper; |
||||
import org.apache.dolphinscheduler.api.dto.resources.FetchFileContentDto; |
||||
import org.apache.dolphinscheduler.dao.entity.Tenant; |
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
import org.apache.dolphinscheduler.dao.repository.TenantDao; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.ResourceMetadata; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.StorageOperator; |
||||
|
||||
import java.util.Locale; |
||||
import java.util.Optional; |
||||
|
||||
import org.junit.jupiter.api.BeforeEach; |
||||
import org.junit.jupiter.api.Test; |
||||
import org.junit.jupiter.api.extension.ExtendWith; |
||||
import org.mockito.InjectMocks; |
||||
import org.mockito.Mock; |
||||
import org.mockito.junit.jupiter.MockitoExtension; |
||||
import org.mockito.junit.jupiter.MockitoSettings; |
||||
import org.mockito.quality.Strictness; |
||||
import org.springframework.context.i18n.LocaleContextHolder; |
||||
|
||||
@MockitoSettings(strictness = Strictness.LENIENT) |
||||
@ExtendWith(MockitoExtension.class) |
||||
class FetchFileContentDtoValidatorTest { |
||||
|
||||
@Mock |
||||
private StorageOperator storageOperator; |
||||
|
||||
@Mock |
||||
private TenantDao tenantDao; |
||||
|
||||
@InjectMocks |
||||
private FetchFileContentDtoValidator fetchFileContentDtoValidator; |
||||
|
||||
private static final String BASE_DIRECTORY = "/tmp/dolphinscheduler"; |
||||
|
||||
private User loginUser; |
||||
|
||||
@BeforeEach |
||||
public void setup() { |
||||
when(storageOperator.getStorageBaseDirectory()).thenReturn(BASE_DIRECTORY); |
||||
loginUser = new User(); |
||||
loginUser.setTenantId(1); |
||||
LocaleContextHolder.setLocale(Locale.ENGLISH); |
||||
} |
||||
|
||||
@Test |
||||
void testValidate_skipLineNumInvalid() { |
||||
FetchFileContentDto fetchFileContentDto = FetchFileContentDto.builder() |
||||
.loginUser(loginUser) |
||||
.resourceFileAbsolutePath("/tmp") |
||||
.skipLineNum(-1) |
||||
.limit(-1) |
||||
.build(); |
||||
assertThrowServiceException( |
||||
"Internal Server Error: skipLineNum must be greater than or equal to 0", |
||||
() -> fetchFileContentDtoValidator.validate(fetchFileContentDto)); |
||||
|
||||
} |
||||
|
||||
@Test |
||||
void testValidate_notUnderBaseDirectory() { |
||||
FetchFileContentDto fetchFileContentDto = FetchFileContentDto.builder() |
||||
.loginUser(loginUser) |
||||
.resourceFileAbsolutePath("/tmp") |
||||
.skipLineNum(0) |
||||
.limit(-1) |
||||
.build(); |
||||
assertThrowServiceException( |
||||
"Internal Server Error: Invalidated resource path: /tmp", |
||||
() -> fetchFileContentDtoValidator.validate(fetchFileContentDto)); |
||||
|
||||
} |
||||
|
||||
@Test |
||||
public void testValidate_filePathContainsIllegalSymbolic() { |
||||
FetchFileContentDto fetchFileContentDto = FetchFileContentDto.builder() |
||||
.loginUser(loginUser) |
||||
.resourceFileAbsolutePath("/tmp/dolphinscheduler/default/resources/..") |
||||
.skipLineNum(0) |
||||
.limit(-1) |
||||
.build(); |
||||
assertThrowServiceException( |
||||
"Internal Server Error: Invalidated resource path: /tmp/dolphinscheduler/default/resources/..", |
||||
() -> fetchFileContentDtoValidator.validate(fetchFileContentDto)); |
||||
} |
||||
|
||||
@Test |
||||
public void testValidate_IsNotFile() { |
||||
FetchFileContentDto fetchFileContentDto = FetchFileContentDto.builder() |
||||
.loginUser(loginUser) |
||||
.resourceFileAbsolutePath("/tmp/dolphinscheduler/default/resources/a") |
||||
.skipLineNum(0) |
||||
.limit(-1) |
||||
.build(); |
||||
assertThrowServiceException( |
||||
"Internal Server Error: The path is not a file: /tmp/dolphinscheduler/default/resources/a", |
||||
() -> fetchFileContentDtoValidator.validate(fetchFileContentDto)); |
||||
} |
||||
|
||||
@Test |
||||
public void testValidate_fileNoPermission() { |
||||
Tenant tenant = new Tenant(); |
||||
tenant.setTenantCode("test"); |
||||
when(tenantDao.queryOptionalById(loginUser.getTenantId())).thenReturn(Optional.of(tenant)); |
||||
|
||||
FetchFileContentDto fetchFileContentDto = FetchFileContentDto.builder() |
||||
.loginUser(loginUser) |
||||
.resourceFileAbsolutePath("/tmp/dolphinscheduler/default/resources/a.sql") |
||||
.skipLineNum(0) |
||||
.limit(-1) |
||||
.build(); |
||||
when(storageOperator.exists(fetchFileContentDto.getResourceFileAbsolutePath())).thenReturn(false); |
||||
when(storageOperator.getResourceMetaData(fetchFileContentDto.getResourceFileAbsolutePath())) |
||||
.thenReturn(ResourceMetadata.builder() |
||||
.resourceAbsolutePath(fetchFileContentDto.getResourceFileAbsolutePath()) |
||||
.resourceBaseDirectory(BASE_DIRECTORY) |
||||
.resourceRelativePath("a.sql") |
||||
.isDirectory(false) |
||||
.tenant("default") |
||||
.build()); |
||||
assertThrowServiceException( |
||||
"Internal Server Error: The user's tenant is test have no permission to access the resource: /tmp/dolphinscheduler/default/resources/a.sql", |
||||
() -> fetchFileContentDtoValidator.validate(fetchFileContentDto)); |
||||
} |
||||
|
||||
@Test |
||||
void validate_fileExtensionInvalid() { |
||||
Tenant tenant = new Tenant(); |
||||
tenant.setTenantCode("default"); |
||||
when(tenantDao.queryOptionalById(loginUser.getTenantId())).thenReturn(Optional.of(tenant)); |
||||
|
||||
FetchFileContentDto fetchFileContentDto = FetchFileContentDto.builder() |
||||
.loginUser(loginUser) |
||||
.resourceFileAbsolutePath("/tmp/dolphinscheduler/default/resources/a.jar") |
||||
.skipLineNum(0) |
||||
.limit(-1) |
||||
.build(); |
||||
when(storageOperator.exists(fetchFileContentDto.getResourceFileAbsolutePath())).thenReturn(false); |
||||
when(storageOperator.getResourceMetaData(fetchFileContentDto.getResourceFileAbsolutePath())) |
||||
.thenReturn(ResourceMetadata.builder() |
||||
.resourceAbsolutePath(fetchFileContentDto.getResourceFileAbsolutePath()) |
||||
.resourceBaseDirectory(BASE_DIRECTORY) |
||||
.resourceRelativePath("a.jar") |
||||
.isDirectory(false) |
||||
.tenant("default") |
||||
.build()); |
||||
assertThrowServiceException( |
||||
"Internal Server Error: The file type: jar cannot be fetched", |
||||
() -> fetchFileContentDtoValidator.validate(fetchFileContentDto)); |
||||
} |
||||
|
||||
@Test |
||||
void validate() { |
||||
Tenant tenant = new Tenant(); |
||||
tenant.setTenantCode("default"); |
||||
when(tenantDao.queryOptionalById(loginUser.getTenantId())).thenReturn(Optional.of(tenant)); |
||||
|
||||
FetchFileContentDto fetchFileContentDto = FetchFileContentDto.builder() |
||||
.loginUser(loginUser) |
||||
.resourceFileAbsolutePath("/tmp/dolphinscheduler/default/resources/a.sql") |
||||
.skipLineNum(0) |
||||
.limit(-1) |
||||
.build(); |
||||
when(storageOperator.exists(fetchFileContentDto.getResourceFileAbsolutePath())).thenReturn(false); |
||||
when(storageOperator.getResourceMetaData(fetchFileContentDto.getResourceFileAbsolutePath())) |
||||
.thenReturn(ResourceMetadata.builder() |
||||
.resourceAbsolutePath(fetchFileContentDto.getResourceFileAbsolutePath()) |
||||
.resourceBaseDirectory(BASE_DIRECTORY) |
||||
.resourceRelativePath("a.sql") |
||||
.isDirectory(false) |
||||
.tenant("default") |
||||
.build()); |
||||
AssertionsHelper.assertDoesNotThrow(() -> fetchFileContentDtoValidator.validate(fetchFileContentDto)); |
||||
} |
||||
} |
@ -0,0 +1,188 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.validator.resource; |
||||
|
||||
import static org.apache.dolphinscheduler.api.AssertionsHelper.assertDoesNotThrow; |
||||
import static org.apache.dolphinscheduler.api.AssertionsHelper.assertThrowServiceException; |
||||
import static org.mockito.Mockito.when; |
||||
|
||||
import org.apache.dolphinscheduler.api.dto.resources.RenameDirectoryDto; |
||||
import org.apache.dolphinscheduler.dao.entity.Tenant; |
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
import org.apache.dolphinscheduler.dao.repository.TenantDao; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.ResourceMetadata; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.StorageOperator; |
||||
|
||||
import java.util.Locale; |
||||
import java.util.Optional; |
||||
|
||||
import org.junit.jupiter.api.BeforeEach; |
||||
import org.junit.jupiter.api.Test; |
||||
import org.junit.jupiter.api.extension.ExtendWith; |
||||
import org.mockito.InjectMocks; |
||||
import org.mockito.Mock; |
||||
import org.mockito.junit.jupiter.MockitoExtension; |
||||
import org.springframework.context.i18n.LocaleContextHolder; |
||||
|
||||
@ExtendWith(MockitoExtension.class) |
||||
class RenameDirectoryDtoValidatorTest { |
||||
|
||||
@Mock |
||||
private StorageOperator storageOperator; |
||||
|
||||
@Mock |
||||
private TenantDao tenantDao; |
||||
|
||||
@InjectMocks |
||||
private RenameDirectoryDtoValidator renameDirectoryDtoValidator; |
||||
|
||||
private static final String BASE_DIRECTORY = "/tmp/dolphinscheduler"; |
||||
|
||||
private User loginUser; |
||||
|
||||
@BeforeEach |
||||
public void setup() { |
||||
when(storageOperator.getStorageBaseDirectory()).thenReturn(BASE_DIRECTORY); |
||||
loginUser = new User(); |
||||
loginUser.setTenantId(1); |
||||
LocaleContextHolder.setLocale(Locale.ENGLISH); |
||||
} |
||||
|
||||
@Test |
||||
void testValidate_notUnderBaseDirectory() { |
||||
RenameDirectoryDto renameDirectoryDto = RenameDirectoryDto.builder() |
||||
.loginUser(loginUser) |
||||
.originDirectoryAbsolutePath("/tmp") |
||||
.targetDirectoryAbsolutePath("/tmp1") |
||||
.build(); |
||||
assertThrowServiceException( |
||||
"Internal Server Error: Invalidated resource path: /tmp", |
||||
() -> renameDirectoryDtoValidator.validate(renameDirectoryDto)); |
||||
|
||||
} |
||||
|
||||
@Test |
||||
public void testValidate_directoryPathContainsIllegalSymbolic() { |
||||
RenameDirectoryDto renameDirectoryDto = RenameDirectoryDto.builder() |
||||
.loginUser(loginUser) |
||||
.originDirectoryAbsolutePath("/tmp/dolphinscheduler/default/resources/..") |
||||
.targetDirectoryAbsolutePath("/tmp/dolphinscheduler/default/resources/a") |
||||
.build(); |
||||
assertThrowServiceException( |
||||
"Internal Server Error: Invalidated resource path: /tmp/dolphinscheduler/default/resources/..", |
||||
() -> renameDirectoryDtoValidator.validate(renameDirectoryDto)); |
||||
} |
||||
|
||||
@Test |
||||
public void testValidate_originDirectoryNotExist() { |
||||
RenameDirectoryDto renameDirectoryDto = RenameDirectoryDto.builder() |
||||
.loginUser(loginUser) |
||||
.originDirectoryAbsolutePath("/tmp/dolphinscheduler/default/resources/a") |
||||
.targetDirectoryAbsolutePath("/tmp/dolphinscheduler/default/resources/b") |
||||
.build(); |
||||
assertThrowServiceException( |
||||
"Internal Server Error: Thr resource is not exists: /tmp/dolphinscheduler/default/resources/a", |
||||
() -> renameDirectoryDtoValidator.validate(renameDirectoryDto)); |
||||
} |
||||
|
||||
@Test |
||||
public void testValidate_originDirectoryNoPermission() { |
||||
Tenant tenant = new Tenant(); |
||||
tenant.setTenantCode("test"); |
||||
when(tenantDao.queryOptionalById(loginUser.getTenantId())).thenReturn(Optional.of(tenant)); |
||||
|
||||
RenameDirectoryDto renameDirectoryDto = RenameDirectoryDto.builder() |
||||
.loginUser(loginUser) |
||||
.originDirectoryAbsolutePath("/tmp/dolphinscheduler/default/resources/a") |
||||
.targetDirectoryAbsolutePath("/tmp/dolphinscheduler/default/resources/b") |
||||
.build(); |
||||
when(storageOperator.exists(renameDirectoryDto.getOriginDirectoryAbsolutePath())).thenReturn(true); |
||||
when(storageOperator.getResourceMetaData(renameDirectoryDto.getOriginDirectoryAbsolutePath())) |
||||
.thenReturn(ResourceMetadata.builder() |
||||
.resourceAbsolutePath(renameDirectoryDto.getOriginDirectoryAbsolutePath()) |
||||
.resourceBaseDirectory(BASE_DIRECTORY) |
||||
.resourceRelativePath("a") |
||||
.isDirectory(true) |
||||
.tenant("default") |
||||
.build()); |
||||
assertThrowServiceException( |
||||
"Internal Server Error: The user's tenant is test have no permission to access the resource: /tmp/dolphinscheduler/default/resources/a", |
||||
() -> renameDirectoryDtoValidator.validate(renameDirectoryDto)); |
||||
} |
||||
|
||||
@Test |
||||
public void testValidate_targetDirectoryAlreadyExist() { |
||||
Tenant tenant = new Tenant(); |
||||
tenant.setTenantCode("default"); |
||||
when(tenantDao.queryOptionalById(loginUser.getTenantId())).thenReturn(Optional.of(tenant)); |
||||
|
||||
RenameDirectoryDto renameDirectoryDto = RenameDirectoryDto.builder() |
||||
.loginUser(loginUser) |
||||
.originDirectoryAbsolutePath("/tmp/dolphinscheduler/default/resources/a") |
||||
.targetDirectoryAbsolutePath("/tmp/dolphinscheduler/default/resources/b") |
||||
.build(); |
||||
when(storageOperator.exists(renameDirectoryDto.getOriginDirectoryAbsolutePath())).thenReturn(true); |
||||
when(storageOperator.getResourceMetaData(renameDirectoryDto.getOriginDirectoryAbsolutePath())) |
||||
.thenReturn(ResourceMetadata.builder() |
||||
.resourceAbsolutePath(renameDirectoryDto.getOriginDirectoryAbsolutePath()) |
||||
.resourceBaseDirectory(BASE_DIRECTORY) |
||||
.resourceRelativePath("a") |
||||
.isDirectory(true) |
||||
.tenant("default") |
||||
.build()); |
||||
|
||||
when(storageOperator.exists(renameDirectoryDto.getTargetDirectoryAbsolutePath())).thenReturn(true); |
||||
assertThrowServiceException( |
||||
"Internal Server Error: The resource is already exist: /tmp/dolphinscheduler/default/resources/b", |
||||
() -> renameDirectoryDtoValidator.validate(renameDirectoryDto)); |
||||
} |
||||
|
||||
@Test |
||||
public void testValidate() { |
||||
Tenant tenant = new Tenant(); |
||||
tenant.setTenantCode("default"); |
||||
when(tenantDao.queryOptionalById(loginUser.getTenantId())).thenReturn(Optional.of(tenant)); |
||||
|
||||
RenameDirectoryDto renameDirectoryDto = RenameDirectoryDto.builder() |
||||
.loginUser(loginUser) |
||||
.originDirectoryAbsolutePath("/tmp/dolphinscheduler/default/resources/a") |
||||
.targetDirectoryAbsolutePath("/tmp/dolphinscheduler/default/resources/b") |
||||
.build(); |
||||
when(storageOperator.exists(renameDirectoryDto.getOriginDirectoryAbsolutePath())).thenReturn(true); |
||||
when(storageOperator.getResourceMetaData(renameDirectoryDto.getOriginDirectoryAbsolutePath())) |
||||
.thenReturn(ResourceMetadata.builder() |
||||
.resourceAbsolutePath(renameDirectoryDto.getOriginDirectoryAbsolutePath()) |
||||
.resourceBaseDirectory(BASE_DIRECTORY) |
||||
.resourceRelativePath("a") |
||||
.isDirectory(true) |
||||
.tenant("default") |
||||
.build()); |
||||
|
||||
when(storageOperator.exists(renameDirectoryDto.getTargetDirectoryAbsolutePath())).thenReturn(false); |
||||
when(storageOperator.getResourceMetaData(renameDirectoryDto.getTargetDirectoryAbsolutePath())) |
||||
.thenReturn(ResourceMetadata.builder() |
||||
.resourceAbsolutePath(renameDirectoryDto.getOriginDirectoryAbsolutePath()) |
||||
.resourceBaseDirectory(BASE_DIRECTORY) |
||||
.resourceRelativePath("b") |
||||
.isDirectory(true) |
||||
.tenant("default") |
||||
.build()); |
||||
|
||||
assertDoesNotThrow(() -> renameDirectoryDtoValidator.validate(renameDirectoryDto)); |
||||
} |
||||
} |
@ -0,0 +1,202 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.api.validator.resource; |
||||
|
||||
import static org.apache.dolphinscheduler.api.AssertionsHelper.assertThrowServiceException; |
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; |
||||
import static org.mockito.Mockito.when; |
||||
|
||||
import org.apache.dolphinscheduler.api.dto.resources.RenameFileDto; |
||||
import org.apache.dolphinscheduler.dao.entity.Tenant; |
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
import org.apache.dolphinscheduler.dao.repository.TenantDao; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.ResourceMetadata; |
||||
import org.apache.dolphinscheduler.plugin.storage.api.StorageOperator; |
||||
|
||||
import java.util.Locale; |
||||
import java.util.Optional; |
||||
|
||||
import org.junit.jupiter.api.BeforeEach; |
||||
import org.junit.jupiter.api.Test; |
||||
import org.junit.jupiter.api.extension.ExtendWith; |
||||
import org.mockito.InjectMocks; |
||||
import org.mockito.Mock; |
||||
import org.mockito.junit.jupiter.MockitoExtension; |
||||
import org.springframework.context.i18n.LocaleContextHolder; |
||||
|
||||
@ExtendWith(MockitoExtension.class) |
||||
public class RenameFileDtoValidatorTest { |
||||
|
||||
@Mock |
||||
private StorageOperator storageOperator; |
||||
|
||||
@Mock |
||||
private TenantDao tenantDao; |
||||
|
||||
@InjectMocks |
||||
private RenameFileDtoValidator renameFileDtoValidator; |
||||
|
||||
private static final String BASE_DIRECTORY = "/tmp/dolphinscheduler"; |
||||
|
||||
private User loginUser; |
||||
|
||||
@BeforeEach |
||||
public void setup() { |
||||
when(storageOperator.getStorageBaseDirectory()).thenReturn(BASE_DIRECTORY); |
||||
loginUser = new User(); |
||||
loginUser.setTenantId(1); |
||||
LocaleContextHolder.setLocale(Locale.ENGLISH); |
||||
} |
||||
|
||||
@Test |
||||
void testValidate_notUnderBaseDirectory() { |
||||
RenameFileDto renameFileDto = RenameFileDto.builder() |
||||
.loginUser(loginUser) |
||||
.originFileAbsolutePath("/tmp") |
||||
.targetFileAbsolutePath("/tmp1") |
||||
.build(); |
||||
assertThrowServiceException( |
||||
"Internal Server Error: Invalidated resource path: /tmp", |
||||
() -> renameFileDtoValidator.validate(renameFileDto)); |
||||
|
||||
} |
||||
|
||||
@Test |
||||
public void testValidate_fileAbsolutePathContainsIllegalSymbolic() { |
||||
RenameFileDto renameFileDto = RenameFileDto.builder() |
||||
.loginUser(loginUser) |
||||
.originFileAbsolutePath("/tmp/dolphinscheduler/default/resources/../a.txt") |
||||
.targetFileAbsolutePath("/tmp/dolphinscheduler/default/resources/b.txt") |
||||
.build(); |
||||
assertThrowServiceException( |
||||
"Internal Server Error: Invalidated resource path: /tmp/dolphinscheduler/default/resources/../a.txt", |
||||
() -> renameFileDtoValidator.validate(renameFileDto)); |
||||
} |
||||
|
||||
@Test |
||||
public void testValidate_originFileNotExist() { |
||||
RenameFileDto renameFileDto = RenameFileDto.builder() |
||||
.loginUser(loginUser) |
||||
.originFileAbsolutePath("/tmp/dolphinscheduler/default/resources/a.txt") |
||||
.targetFileAbsolutePath("/tmp/dolphinscheduler/default/resources/b.txt") |
||||
.build(); |
||||
assertThrowServiceException( |
||||
"Internal Server Error: Thr resource is not exists: /tmp/dolphinscheduler/default/resources/a.txt", |
||||
() -> renameFileDtoValidator.validate(renameFileDto)); |
||||
} |
||||
|
||||
@Test |
||||
public void testValidate_originFileIsNotFile() { |
||||
RenameFileDto renameFileDto = RenameFileDto.builder() |
||||
.loginUser(loginUser) |
||||
.originFileAbsolutePath("/tmp/dolphinscheduler/default/resources/a") |
||||
.targetFileAbsolutePath("/tmp/dolphinscheduler/default/resources/b.txt") |
||||
.build(); |
||||
when(storageOperator.exists(renameFileDto.getOriginFileAbsolutePath())).thenReturn(true); |
||||
assertThrowServiceException( |
||||
"Internal Server Error: The path is not a file: /tmp/dolphinscheduler/default/resources/a", |
||||
() -> renameFileDtoValidator.validate(renameFileDto)); |
||||
} |
||||
|
||||
@Test |
||||
public void testValidate_originFileNoPermission() { |
||||
Tenant tenant = new Tenant(); |
||||
tenant.setTenantCode("test"); |
||||
when(tenantDao.queryOptionalById(loginUser.getTenantId())).thenReturn(Optional.of(tenant)); |
||||
|
||||
RenameFileDto renameFileDto = RenameFileDto.builder() |
||||
.loginUser(loginUser) |
||||
.originFileAbsolutePath("/tmp/dolphinscheduler/default/resources/a.txt") |
||||
.targetFileAbsolutePath("/tmp/dolphinscheduler/default/resources/b.txt") |
||||
.build(); |
||||
when(storageOperator.exists(renameFileDto.getOriginFileAbsolutePath())).thenReturn(true); |
||||
when(storageOperator.getResourceMetaData(renameFileDto.getOriginFileAbsolutePath())) |
||||
.thenReturn(ResourceMetadata.builder() |
||||
.resourceAbsolutePath(renameFileDto.getOriginFileAbsolutePath()) |
||||
.resourceBaseDirectory(BASE_DIRECTORY) |
||||
.resourceRelativePath("a.txt") |
||||
.isDirectory(false) |
||||
.tenant("default") |
||||
.build()); |
||||
assertThrowServiceException( |
||||
"Internal Server Error: The user's tenant is test have no permission to access the resource: /tmp/dolphinscheduler/default/resources/a.txt", |
||||
() -> renameFileDtoValidator.validate(renameFileDto)); |
||||
} |
||||
|
||||
@Test |
||||
public void testValidate_targetFileAlreadyExist() { |
||||
Tenant tenant = new Tenant(); |
||||
tenant.setTenantCode("default"); |
||||
when(tenantDao.queryOptionalById(loginUser.getTenantId())).thenReturn(Optional.of(tenant)); |
||||
|
||||
RenameFileDto renameDirectoryDto = RenameFileDto.builder() |
||||
.loginUser(loginUser) |
||||
.originFileAbsolutePath("/tmp/dolphinscheduler/default/resources/a.txt") |
||||
.targetFileAbsolutePath("/tmp/dolphinscheduler/default/resources/b.txt") |
||||
.build(); |
||||
when(storageOperator.exists(renameDirectoryDto.getOriginFileAbsolutePath())).thenReturn(true); |
||||
when(storageOperator.getResourceMetaData(renameDirectoryDto.getOriginFileAbsolutePath())) |
||||
.thenReturn(ResourceMetadata.builder() |
||||
.resourceAbsolutePath(renameDirectoryDto.getOriginFileAbsolutePath()) |
||||
.resourceBaseDirectory(BASE_DIRECTORY) |
||||
.resourceRelativePath("a.txt") |
||||
.isDirectory(false) |
||||
.tenant("default") |
||||
.build()); |
||||
|
||||
when(storageOperator.exists(renameDirectoryDto.getTargetFileAbsolutePath())).thenReturn(true); |
||||
assertThrowServiceException( |
||||
"Internal Server Error: The resource is already exist: /tmp/dolphinscheduler/default/resources/b.txt", |
||||
() -> renameFileDtoValidator.validate(renameDirectoryDto)); |
||||
} |
||||
|
||||
@Test |
||||
public void testValidate() { |
||||
Tenant tenant = new Tenant(); |
||||
tenant.setTenantCode("default"); |
||||
when(tenantDao.queryOptionalById(loginUser.getTenantId())).thenReturn(Optional.of(tenant)); |
||||
|
||||
RenameFileDto renameDirectoryDto = RenameFileDto.builder() |
||||
.loginUser(loginUser) |
||||
.originFileAbsolutePath("/tmp/dolphinscheduler/default/resources/a.txt") |
||||
.targetFileAbsolutePath("/tmp/dolphinscheduler/default/resources/b.txt") |
||||
.build(); |
||||
when(storageOperator.exists(renameDirectoryDto.getOriginFileAbsolutePath())).thenReturn(true); |
||||
when(storageOperator.getResourceMetaData(renameDirectoryDto.getOriginFileAbsolutePath())) |
||||
.thenReturn(ResourceMetadata.builder() |
||||
.resourceAbsolutePath(renameDirectoryDto.getOriginFileAbsolutePath()) |
||||
.resourceBaseDirectory(BASE_DIRECTORY) |
||||
.resourceRelativePath("a.txt") |
||||
.isDirectory(false) |
||||
.tenant("default") |
||||
.build()); |
||||
|
||||
when(storageOperator.exists(renameDirectoryDto.getTargetFileAbsolutePath())).thenReturn(false); |
||||
when(storageOperator.getResourceMetaData(renameDirectoryDto.getTargetFileAbsolutePath())) |
||||
.thenReturn(ResourceMetadata.builder() |
||||
.resourceAbsolutePath(renameDirectoryDto.getTargetFileAbsolutePath()) |
||||
.resourceBaseDirectory(BASE_DIRECTORY) |
||||
.resourceRelativePath("b.txt") |
||||
.isDirectory(false) |
||||
.tenant("default") |
||||
.build()); |
||||
|
||||
assertDoesNotThrow(() -> renameFileDtoValidator.validate(renameDirectoryDto)); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,24 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.dao.repository; |
||||
|
||||
import org.apache.dolphinscheduler.dao.entity.Tenant; |
||||
|
||||
public interface TenantDao extends IDao<Tenant> { |
||||
|
||||
} |
@ -0,0 +1,36 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.dao.repository.impl; |
||||
|
||||
import org.apache.dolphinscheduler.dao.entity.Tenant; |
||||
import org.apache.dolphinscheduler.dao.mapper.TenantMapper; |
||||
import org.apache.dolphinscheduler.dao.repository.BaseDao; |
||||
import org.apache.dolphinscheduler.dao.repository.TenantDao; |
||||
|
||||
import lombok.NonNull; |
||||
|
||||
import org.springframework.stereotype.Repository; |
||||
|
||||
@Repository |
||||
public class TenantDaoImpl extends BaseDao<Tenant, TenantMapper> implements TenantDao { |
||||
|
||||
public TenantDaoImpl(@NonNull TenantMapper tenantMapper) { |
||||
super(tenantMapper); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,36 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.storage.abs; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
@Data |
||||
@Builder |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class AbsStorageProperties { |
||||
|
||||
private String containerName; |
||||
private String connectionString; |
||||
private String storageAccountName; |
||||
private String resourceUploadPath; |
||||
|
||||
} |
@ -1,274 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.storage.abs; |
||||
|
||||
import static org.apache.dolphinscheduler.common.constants.Constants.FOLDER_SEPARATOR; |
||||
import static org.apache.dolphinscheduler.common.constants.Constants.FORMAT_S_S; |
||||
import static org.mockito.ArgumentMatchers.anyString; |
||||
import static org.mockito.Mockito.doNothing; |
||||
import static org.mockito.Mockito.doReturn; |
||||
import static org.mockito.Mockito.times; |
||||
import static org.mockito.Mockito.verify; |
||||
|
||||
import org.apache.dolphinscheduler.plugin.storage.api.StorageEntity; |
||||
import org.apache.dolphinscheduler.spi.enums.ResourceType; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
import org.junit.jupiter.api.Assertions; |
||||
import org.junit.jupiter.api.BeforeEach; |
||||
import org.junit.jupiter.api.Test; |
||||
import org.junit.jupiter.api.extension.ExtendWith; |
||||
import org.mockito.Mock; |
||||
import org.mockito.Mockito; |
||||
import org.mockito.junit.jupiter.MockitoExtension; |
||||
|
||||
import com.azure.storage.blob.BlobClient; |
||||
import com.azure.storage.blob.BlobContainerClient; |
||||
import com.azure.storage.blob.BlobServiceClient; |
||||
import com.azure.storage.blob.specialized.BlockBlobClient; |
||||
|
||||
@ExtendWith(MockitoExtension.class) |
||||
public class AbsStorageOperatorTest { |
||||
|
||||
private static final String CONNECTION_STRING_MOCK = "CONNECTION_STRING_MOCK"; |
||||
|
||||
private static final String ACCOUNT_NAME_MOCK = "ACCOUNT_NAME_MOCK"; |
||||
|
||||
private static final String CONTAINER_NAME_MOCK = "CONTAINER_NAME_MOCK"; |
||||
|
||||
private static final String TENANT_CODE_MOCK = "TENANT_CODE_MOCK"; |
||||
|
||||
private static final String DIR_MOCK = "DIR_MOCK"; |
||||
|
||||
private static final String FILE_NAME_MOCK = "FILE_NAME_MOCK"; |
||||
|
||||
private static final String FILE_PATH_MOCK = "FILE_PATH_MOCK"; |
||||
|
||||
private static final String FULL_NAME = "/tmp/dir1/"; |
||||
|
||||
private static final String DEFAULT_PATH = "/tmp/"; |
||||
|
||||
@Mock |
||||
private BlobContainerClient blobContainerClient; |
||||
|
||||
@Mock |
||||
private BlobServiceClient blobServiceClient; |
||||
|
||||
@Mock |
||||
private BlockBlobClient blockBlobClient; |
||||
|
||||
@Mock |
||||
private BlobClient blobClient; |
||||
|
||||
private AbsStorageOperator absStorageOperator; |
||||
|
||||
@BeforeEach |
||||
public void setUp() throws Exception { |
||||
absStorageOperator = Mockito.spy(AbsStorageOperator.class); |
||||
Mockito.doReturn(CONNECTION_STRING_MOCK).when(absStorageOperator).readConnectionString(); |
||||
Mockito.doReturn(CONTAINER_NAME_MOCK).when(absStorageOperator).readContainerName(); |
||||
Mockito.doReturn(ACCOUNT_NAME_MOCK).when(absStorageOperator).readAccountName(); |
||||
Mockito.doReturn(blobContainerClient).when(absStorageOperator).buildBlobContainerClient(); |
||||
Mockito.doReturn(blobServiceClient).when(absStorageOperator).buildBlobServiceClient(); |
||||
Mockito.doNothing().when(absStorageOperator).checkContainerNameExists(); |
||||
|
||||
absStorageOperator.init(); |
||||
} |
||||
|
||||
@Test |
||||
public void testInit() throws Exception { |
||||
verify(absStorageOperator, times(1)).buildBlobServiceClient(); |
||||
verify(absStorageOperator, times(1)).buildBlobContainerClient(); |
||||
Assertions.assertEquals(CONNECTION_STRING_MOCK, absStorageOperator.getConnectionString()); |
||||
Assertions.assertEquals(CONTAINER_NAME_MOCK, absStorageOperator.getContainerName()); |
||||
Assertions.assertEquals(ACCOUNT_NAME_MOCK, absStorageOperator.getStorageAccountName()); |
||||
} |
||||
|
||||
@Test |
||||
public void createTenantResAndUdfDir() throws Exception { |
||||
doReturn(DIR_MOCK).when(absStorageOperator).getAbsResDir(TENANT_CODE_MOCK); |
||||
doReturn(DIR_MOCK).when(absStorageOperator).getAbsUdfDir(TENANT_CODE_MOCK); |
||||
doReturn(true).when(absStorageOperator).mkdir(TENANT_CODE_MOCK, DIR_MOCK); |
||||
absStorageOperator.createTenantDirIfNotExists(TENANT_CODE_MOCK); |
||||
verify(absStorageOperator, times(2)).mkdir(TENANT_CODE_MOCK, DIR_MOCK); |
||||
} |
||||
|
||||
@Test |
||||
public void getResDir() { |
||||
final String expectedResourceDir = String.format("dolphinscheduler/%s/resources/", TENANT_CODE_MOCK); |
||||
final String dir = absStorageOperator.getResDir(TENANT_CODE_MOCK); |
||||
Assertions.assertEquals(expectedResourceDir, dir); |
||||
} |
||||
|
||||
@Test |
||||
public void getUdfDir() { |
||||
final String expectedUdfDir = String.format("dolphinscheduler/%s/udfs/", TENANT_CODE_MOCK); |
||||
final String dir = absStorageOperator.getUdfDir(TENANT_CODE_MOCK); |
||||
Assertions.assertEquals(expectedUdfDir, dir); |
||||
} |
||||
|
||||
@Test |
||||
public void mkdirWhenDirExists() { |
||||
boolean isSuccess = false; |
||||
try { |
||||
final String key = DIR_MOCK + FOLDER_SEPARATOR; |
||||
Mockito.doReturn(true).when(absStorageOperator).isObjectExists(key); |
||||
isSuccess = absStorageOperator.mkdir(TENANT_CODE_MOCK, DIR_MOCK); |
||||
|
||||
} catch (IOException e) { |
||||
Assertions.fail("test failed due to unexpected IO exception"); |
||||
} |
||||
|
||||
Assertions.assertTrue(isSuccess); |
||||
} |
||||
|
||||
@Test |
||||
public void getResourceFullName() { |
||||
final String expectedResourceFileName = |
||||
String.format("dolphinscheduler/%s/resources/%s", TENANT_CODE_MOCK, FILE_NAME_MOCK); |
||||
final String resourceFileName = absStorageOperator.getResourceFullName(TENANT_CODE_MOCK, FILE_NAME_MOCK); |
||||
Assertions.assertEquals(expectedResourceFileName, resourceFileName); |
||||
} |
||||
|
||||
@Test |
||||
public void getFileName() { |
||||
final String expectedFileName = |
||||
String.format("dolphinscheduler/%s/resources/%s", TENANT_CODE_MOCK, FILE_NAME_MOCK); |
||||
final String fileName = absStorageOperator.getFileName(ResourceType.FILE, TENANT_CODE_MOCK, FILE_NAME_MOCK); |
||||
Assertions.assertEquals(expectedFileName, fileName); |
||||
} |
||||
|
||||
@Test |
||||
public void exists() { |
||||
boolean doesExist = false; |
||||
doReturn(true).when(absStorageOperator).isObjectExists(FILE_NAME_MOCK); |
||||
try { |
||||
doesExist = absStorageOperator.exists(FILE_NAME_MOCK); |
||||
} catch (IOException e) { |
||||
Assertions.fail("unexpected IO exception in unit test"); |
||||
} |
||||
|
||||
Assertions.assertTrue(doesExist); |
||||
} |
||||
|
||||
@Test |
||||
public void delete() { |
||||
boolean isDeleted = false; |
||||
doReturn(true).when(absStorageOperator).isObjectExists(FILE_NAME_MOCK); |
||||
Mockito.doReturn(blobClient).when(blobContainerClient).getBlobClient(Mockito.anyString()); |
||||
try { |
||||
isDeleted = absStorageOperator.delete(FILE_NAME_MOCK, true); |
||||
} catch (IOException e) { |
||||
Assertions.fail("unexpected IO exception in unit test"); |
||||
} |
||||
|
||||
Assertions.assertTrue(isDeleted); |
||||
verify(blobClient, times(1)).delete(); |
||||
} |
||||
|
||||
@Test |
||||
public void copy() { |
||||
boolean isSuccess = false; |
||||
Mockito.doReturn(blobClient).when(blobContainerClient).getBlobClient(Mockito.anyString()); |
||||
Mockito.doReturn(blockBlobClient).when(blobClient).getBlockBlobClient(); |
||||
try { |
||||
isSuccess = absStorageOperator.copy(FILE_PATH_MOCK, FILE_PATH_MOCK, false, false); |
||||
} catch (IOException e) { |
||||
Assertions.fail("unexpected IO exception in unit test"); |
||||
} |
||||
|
||||
Assertions.assertTrue(isSuccess); |
||||
} |
||||
|
||||
@Test |
||||
public void deleteTenant() { |
||||
doNothing().when(absStorageOperator).deleteTenantCode(anyString()); |
||||
try { |
||||
absStorageOperator.deleteTenant(TENANT_CODE_MOCK); |
||||
} catch (Exception e) { |
||||
Assertions.fail("unexpected exception caught in unit test"); |
||||
} |
||||
|
||||
verify(absStorageOperator, times(1)).deleteTenantCode(anyString()); |
||||
} |
||||
|
||||
@Test |
||||
public void getGcsResDir() { |
||||
final String expectedGcsResDir = String.format("dolphinscheduler/%s/resources", TENANT_CODE_MOCK); |
||||
final String gcsResDir = absStorageOperator.getAbsResDir(TENANT_CODE_MOCK); |
||||
Assertions.assertEquals(expectedGcsResDir, gcsResDir); |
||||
} |
||||
|
||||
@Test |
||||
public void getGcsUdfDir() { |
||||
final String expectedGcsUdfDir = String.format("dolphinscheduler/%s/udfs", TENANT_CODE_MOCK); |
||||
final String gcsUdfDir = absStorageOperator.getAbsUdfDir(TENANT_CODE_MOCK); |
||||
Assertions.assertEquals(expectedGcsUdfDir, gcsUdfDir); |
||||
} |
||||
|
||||
@Test |
||||
public void getGcsTenantDir() { |
||||
final String expectedGcsTenantDir = String.format(FORMAT_S_S, DIR_MOCK, TENANT_CODE_MOCK); |
||||
doReturn(DIR_MOCK).when(absStorageOperator).getGcsDataBasePath(); |
||||
final String gcsTenantDir = absStorageOperator.getAbsTenantDir(TENANT_CODE_MOCK); |
||||
Assertions.assertEquals(expectedGcsTenantDir, gcsTenantDir); |
||||
} |
||||
|
||||
@Test |
||||
public void deleteDir() { |
||||
Mockito.doReturn(blobClient).when(blobContainerClient).getBlobClient(Mockito.anyString()); |
||||
doReturn(true).when(absStorageOperator).isObjectExists(Mockito.any()); |
||||
absStorageOperator.deleteDirectory(DIR_MOCK); |
||||
verify(blobClient, times(1)).delete(); |
||||
} |
||||
|
||||
@Test |
||||
public void testGetFileStatus() throws Exception { |
||||
StorageEntity entity = |
||||
absStorageOperator.getFileStatus(FULL_NAME, DEFAULT_PATH, TENANT_CODE_MOCK, ResourceType.FILE); |
||||
Assertions.assertEquals(FULL_NAME, entity.getFullName()); |
||||
Assertions.assertEquals("dir1/", entity.getFileName()); |
||||
} |
||||
|
||||
@Test |
||||
public void testListFilesStatus() throws Exception { |
||||
Mockito.doReturn(null).when(blobContainerClient).listBlobsByHierarchy(Mockito.any()); |
||||
List<StorageEntity> result = |
||||
absStorageOperator.listFilesStatus(FULL_NAME, DEFAULT_PATH, TENANT_CODE_MOCK, ResourceType.FILE); |
||||
verify(blobContainerClient, times(1)).listBlobsByHierarchy(Mockito.any()); |
||||
} |
||||
|
||||
@Test |
||||
public void testListFilesStatusRecursively() throws Exception { |
||||
StorageEntity entity = new StorageEntity(); |
||||
entity.setFullName(FULL_NAME); |
||||
|
||||
doReturn(entity).when(absStorageOperator).getFileStatus(FULL_NAME, DEFAULT_PATH, TENANT_CODE_MOCK, |
||||
ResourceType.FILE); |
||||
doReturn(Collections.EMPTY_LIST).when(absStorageOperator).listFilesStatus(anyString(), anyString(), anyString(), |
||||
Mockito.any(ResourceType.class)); |
||||
|
||||
List<StorageEntity> result = |
||||
absStorageOperator.listFilesStatusRecursively(FULL_NAME, DEFAULT_PATH, TENANT_CODE_MOCK, |
||||
ResourceType.FILE); |
||||
Assertions.assertEquals(0, result.size()); |
||||
} |
||||
} |
@ -0,0 +1,110 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.storage.api; |
||||
|
||||
import org.apache.dolphinscheduler.common.constants.Constants; |
||||
import org.apache.dolphinscheduler.common.utils.FileUtils; |
||||
import org.apache.dolphinscheduler.common.utils.PropertyUtils; |
||||
import org.apache.dolphinscheduler.spi.enums.ResourceType; |
||||
|
||||
import org.apache.commons.lang3.StringUtils; |
||||
|
||||
import java.io.File; |
||||
|
||||
import com.google.common.base.Preconditions; |
||||
import com.google.common.io.Files; |
||||
|
||||
public abstract class AbstractStorageOperator implements StorageOperator { |
||||
|
||||
protected final String resourceBaseAbsolutePath; |
||||
|
||||
public AbstractStorageOperator(String resourceBaseAbsolutePath) { |
||||
Preconditions.checkNotNull(resourceBaseAbsolutePath, "Resource upload path should not be null"); |
||||
this.resourceBaseAbsolutePath = resourceBaseAbsolutePath; |
||||
} |
||||
|
||||
@Override |
||||
public ResourceMetadata getResourceMetaData(String resourceAbsolutePath) { |
||||
String storageBaseDirectory = getStorageBaseDirectory(); |
||||
String resourceSegment = StringUtils.substringAfter(resourceAbsolutePath, storageBaseDirectory); |
||||
String[] segments = StringUtils.split(resourceSegment, File.separator, 3); |
||||
if (segments.length == 0) { |
||||
throw new IllegalArgumentException("Invalid resource path: " + resourceAbsolutePath); |
||||
} |
||||
return ResourceMetadata.builder() |
||||
.resourceAbsolutePath(resourceAbsolutePath) |
||||
.resourceBaseDirectory(storageBaseDirectory) |
||||
.isDirectory(Files.getFileExtension(resourceAbsolutePath).isEmpty()) |
||||
.tenant(segments[0]) |
||||
.resourceType(segments[1].equals(FILE_FOLDER_NAME) ? ResourceType.FILE : ResourceType.UDF) |
||||
.resourceRelativePath(segments.length == 2 ? "/" : segments[2]) |
||||
.resourceParentAbsolutePath(StringUtils.substringBeforeLast(resourceAbsolutePath, File.separator)) |
||||
.build(); |
||||
} |
||||
|
||||
@Override |
||||
public String getStorageBaseDirectory() { |
||||
// All directory should end with File.separator
|
||||
return PropertyUtils.getString(Constants.RESOURCE_UPLOAD_PATH, "/dolphinscheduler"); |
||||
} |
||||
|
||||
@Override |
||||
public String getStorageBaseDirectory(String tenantCode) { |
||||
if (StringUtils.isEmpty(tenantCode)) { |
||||
throw new IllegalArgumentException("Tenant code should not be empty"); |
||||
} |
||||
// All directory should end with File.separator
|
||||
return FileUtils.concatFilePath(getStorageBaseDirectory(), tenantCode); |
||||
} |
||||
|
||||
@Override |
||||
public String getStorageBaseDirectory(String tenantCode, ResourceType resourceType) { |
||||
String tenantBaseDirectory = getStorageBaseDirectory(tenantCode); |
||||
if (resourceType == null) { |
||||
throw new IllegalArgumentException("Resource type should not be null"); |
||||
} |
||||
String resourceBaseDirectory; |
||||
switch (resourceType) { |
||||
case FILE: |
||||
resourceBaseDirectory = FileUtils.concatFilePath(tenantBaseDirectory, FILE_FOLDER_NAME); |
||||
break; |
||||
case UDF: |
||||
resourceBaseDirectory = FileUtils.concatFilePath(tenantBaseDirectory, UDF_FOLDER_NAME); |
||||
break; |
||||
case ALL: |
||||
resourceBaseDirectory = tenantBaseDirectory; |
||||
break; |
||||
default: |
||||
throw new IllegalArgumentException("Resource type: " + resourceType + " not supported"); |
||||
} |
||||
// All directory should end with File.separator
|
||||
return resourceBaseDirectory; |
||||
} |
||||
|
||||
@Override |
||||
public String getStorageFileAbsolutePath(String tenantCode, String fileName) { |
||||
return FileUtils.concatFilePath(getStorageBaseDirectory(tenantCode, ResourceType.FILE), fileName); |
||||
} |
||||
|
||||
protected void exceptionIfPathEmpty(String resourceAbsolutePath) { |
||||
if (StringUtils.isEmpty(resourceAbsolutePath)) { |
||||
throw new IllegalArgumentException("Resource path should not be empty"); |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,42 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.storage.api; |
||||
|
||||
import org.apache.dolphinscheduler.spi.enums.ResourceType; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
@Data |
||||
@Builder |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class ResourceMetadata { |
||||
|
||||
private String resourceAbsolutePath; |
||||
|
||||
private String resourceBaseDirectory; |
||||
private String tenant; |
||||
private ResourceType resourceType; |
||||
private String resourceRelativePath; |
||||
private String resourceParentAbsolutePath; |
||||
private boolean isDirectory; |
||||
|
||||
} |
@ -1,203 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.storage.api; |
||||
|
||||
import static org.apache.dolphinscheduler.common.constants.Constants.RESOURCE_TYPE_FILE; |
||||
|
||||
import org.apache.dolphinscheduler.common.constants.Constants; |
||||
import org.apache.dolphinscheduler.common.enums.ResUploadType; |
||||
import org.apache.dolphinscheduler.common.utils.PropertyUtils; |
||||
import org.apache.dolphinscheduler.spi.enums.ResourceType; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.List; |
||||
|
||||
public interface StorageOperate { |
||||
|
||||
String RESOURCE_UPLOAD_PATH = PropertyUtils.getString(Constants.RESOURCE_UPLOAD_PATH, "/dolphinscheduler"); |
||||
|
||||
/** |
||||
* if the resource of tenant 's exist, the resource of folder will be created |
||||
* @param tenantCode |
||||
* @throws Exception |
||||
*/ |
||||
void createTenantDirIfNotExists(String tenantCode) throws Exception; |
||||
|
||||
/** |
||||
* get the resource directory of tenant |
||||
* @param tenantCode |
||||
* @return |
||||
*/ |
||||
String getResDir(String tenantCode); |
||||
|
||||
/** |
||||
* return the udf directory of tenant |
||||
* @param tenantCode |
||||
* @return |
||||
*/ |
||||
String getUdfDir(String tenantCode); |
||||
|
||||
/** |
||||
* create the directory that the path of tenant wanted to create |
||||
* @param tenantCode |
||||
* @param path |
||||
* @return |
||||
* @throws IOException |
||||
*/ |
||||
boolean mkdir(String tenantCode, String path) throws IOException; |
||||
|
||||
/** |
||||
* get the path of the resource file (fullName) |
||||
* @param tenantCode |
||||
* @param fileName |
||||
* @return |
||||
*/ |
||||
String getResourceFullName(String tenantCode, String fileName); |
||||
|
||||
/** |
||||
* get the path of the resource file excluding the base path (fileName) |
||||
*/ |
||||
default String getResourceFileName(String tenantCode, String fullName) { |
||||
String resDir = getResDir(tenantCode); |
||||
String filenameReplaceResDir = fullName.replaceFirst(resDir, ""); |
||||
if (!filenameReplaceResDir.equals(fullName)) { |
||||
return filenameReplaceResDir; |
||||
} |
||||
|
||||
// Replace resource dir not effective in case of run workflow with different tenant from resource file's.
|
||||
// this is backup solution to get related path, by split with RESOURCE_TYPE_FILE
|
||||
return filenameReplaceResDir.contains(RESOURCE_TYPE_FILE) |
||||
? filenameReplaceResDir.split(String.format("%s/", RESOURCE_TYPE_FILE))[1] |
||||
: filenameReplaceResDir; |
||||
} |
||||
|
||||
/** |
||||
* get the path of the file |
||||
* @param resourceType |
||||
* @param tenantCode |
||||
* @param fileName |
||||
* @return |
||||
*/ |
||||
String getFileName(ResourceType resourceType, String tenantCode, String fileName); |
||||
|
||||
/** |
||||
* predicate if the resource of tenant exists |
||||
* @param fullName |
||||
* @return |
||||
* @throws IOException |
||||
*/ |
||||
boolean exists(String fullName) throws IOException; |
||||
|
||||
/** |
||||
* delete the resource of filePath |
||||
* todo if the filePath is the type of directory ,the files in the filePath need to be deleted at all |
||||
* @param filePath |
||||
* @param recursive |
||||
* @return |
||||
* @throws IOException |
||||
*/ |
||||
boolean delete(String filePath, boolean recursive) throws IOException; |
||||
|
||||
boolean delete(String filePath, List<String> childrenPathArray, boolean recursive) throws IOException; |
||||
|
||||
/** |
||||
* copy the file from srcPath to dstPath |
||||
* @param srcPath |
||||
* @param dstPath |
||||
* @param deleteSource if need to delete the file of srcPath |
||||
* @param overwrite |
||||
* @return |
||||
* @throws IOException |
||||
*/ |
||||
boolean copy(String srcPath, String dstPath, boolean deleteSource, boolean overwrite) throws IOException; |
||||
|
||||
/** |
||||
* get the root path of the tenant with resourceType |
||||
* @param resourceType |
||||
* @param tenantCode |
||||
* @return |
||||
*/ |
||||
String getDir(ResourceType resourceType, String tenantCode); |
||||
|
||||
/** |
||||
* upload the local srcFile to dstPath |
||||
* @param tenantCode |
||||
* @param srcFile |
||||
* @param dstPath |
||||
* @param deleteSource |
||||
* @param overwrite |
||||
* @return |
||||
* @throws IOException |
||||
*/ |
||||
boolean upload(String tenantCode, String srcFile, String dstPath, boolean deleteSource, |
||||
boolean overwrite) throws IOException; |
||||
|
||||
/** |
||||
* download the srcPath to local |
||||
* |
||||
* @param srcFilePath the full path of the srcPath |
||||
* @param dstFile |
||||
* @param overwrite |
||||
* @throws IOException |
||||
*/ |
||||
void download(String srcFilePath, String dstFile, boolean overwrite) throws IOException; |
||||
|
||||
/** |
||||
* vim the context of filePath |
||||
* @param tenantCode |
||||
* @param filePath |
||||
* @param skipLineNums |
||||
* @param limit |
||||
* @return |
||||
* @throws IOException |
||||
*/ |
||||
List<String> vimFile(String tenantCode, String filePath, int skipLineNums, int limit) throws IOException; |
||||
|
||||
/** |
||||
* delete the files and directory of the tenant |
||||
* |
||||
* @param tenantCode |
||||
* @throws Exception |
||||
*/ |
||||
void deleteTenant(String tenantCode) throws Exception; |
||||
|
||||
/** |
||||
* return the storageType |
||||
* |
||||
* @return |
||||
*/ |
||||
ResUploadType returnStorageType(); |
||||
|
||||
/** |
||||
* return files and folders in the current directory and subdirectories |
||||
* */ |
||||
List<StorageEntity> listFilesStatusRecursively(String path, String defaultPath, String tenantCode, |
||||
ResourceType type); |
||||
|
||||
/** |
||||
* return files and folders in the current directory |
||||
* */ |
||||
List<StorageEntity> listFilesStatus(String path, String defaultPath, String tenantCode, |
||||
ResourceType type) throws Exception; |
||||
|
||||
/** |
||||
* return a file status |
||||
* */ |
||||
StorageEntity getFileStatus(String path, String defaultPath, String tenantCode, |
||||
ResourceType type) throws Exception; |
||||
} |
@ -0,0 +1,157 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.storage.api; |
||||
|
||||
import org.apache.dolphinscheduler.spi.enums.ResourceType; |
||||
|
||||
import java.nio.file.FileAlreadyExistsException; |
||||
import java.util.List; |
||||
|
||||
public interface StorageOperator { |
||||
|
||||
String FILE_FOLDER_NAME = "resources"; |
||||
String UDF_FOLDER_NAME = "udfs"; |
||||
|
||||
ResourceMetadata getResourceMetaData(String resourceAbsolutePath); |
||||
|
||||
/** |
||||
* Get the absolute path of base directory. |
||||
* |
||||
* @return the base directory. e.g. file:///tmp/dolphinscheduler/, /tmp/dolphinscheduler/
|
||||
*/ |
||||
String getStorageBaseDirectory(); |
||||
|
||||
/** |
||||
* Get the absolute path of directory which will be used by the given tenant. the tenant directory is under the base directory. |
||||
* |
||||
* @param tenantCode the tenant code, cannot be empty |
||||
* @return the tenant directory. e.g. file:///tmp/dolphinscheduler/default/
|
||||
*/ |
||||
String getStorageBaseDirectory(String tenantCode); |
||||
|
||||
/** |
||||
* Get the absolute path of directory which will be used by the given tenant and resource type. the resource directory is under the tenant directory. |
||||
* <p> If the resource type is FILE, will be 'file:///tmp/dolphinscheduler/default/resources/'.
|
||||
* <p> If the resource type is UDF, will be 'is file:///tmp/dolphinscheduler/default/udfs/'.
|
||||
* <p> If the resource type is ALL, will be 'is file:///tmp/dolphinscheduler/default/'.
|
||||
* |
||||
* @param tenantCode the tenant code, cannot be empty |
||||
* @param resourceType the resource type, cannot be null |
||||
* @return the resource directory. e.g. file:///tmp/dolphinscheduler/default/resources/
|
||||
*/ |
||||
String getStorageBaseDirectory(String tenantCode, ResourceType resourceType); |
||||
|
||||
/** |
||||
* Get the absolute path of the file in the storage. the file will under the file resource directory. |
||||
* |
||||
* @param tenantCode the tenant code, cannot be empty |
||||
* @param fileName the file name, cannot be empty |
||||
* @return the file absolute path. e.g. file:///tmp/dolphinscheduler/default/resources/test.sh
|
||||
*/ |
||||
String getStorageFileAbsolutePath(String tenantCode, String fileName); |
||||
|
||||
/** |
||||
* Create a directory if the directory is already exists will throw exception(Dependent on the storage implementation). |
||||
* <p> If the directory is not exists, will create the directory. |
||||
* <p> If the parent directory is not exists, will create the parent directory. |
||||
* <p> If the directory is already exists, will throw {@link FileAlreadyExistsException}. |
||||
* |
||||
* @param directoryAbsolutePath the directory absolute path |
||||
*/ |
||||
void createStorageDir(String directoryAbsolutePath); |
||||
|
||||
/** |
||||
* Check if the resource exists. |
||||
* |
||||
* @param resourceAbsolutePath the resource absolute path |
||||
* @return true if the resource exists, otherwise false |
||||
*/ |
||||
boolean exists(String resourceAbsolutePath); |
||||
|
||||
/** |
||||
* Delete the resource, if the resourceAbsolutePath is not exists, will do nothing. |
||||
* |
||||
* @param resourceAbsolutePath the resource absolute path |
||||
* @param recursive whether to delete all the sub file/directory under the given resource |
||||
*/ |
||||
void delete(String resourceAbsolutePath, boolean recursive); |
||||
|
||||
/** |
||||
* Copy the resource from the source path to the destination path. |
||||
* |
||||
* @param srcAbsolutePath the source path |
||||
* @param dstAbsolutePath the destination path |
||||
* @param deleteSource whether to delete the source path after copying |
||||
* @param overwrite whether to overwrite the destination path if it exists |
||||
*/ |
||||
void copy(String srcAbsolutePath, String dstAbsolutePath, boolean deleteSource, boolean overwrite); |
||||
|
||||
/** |
||||
* Move the resource from the source path to the destination path. |
||||
* |
||||
* @param srcLocalFileAbsolutePath the source local file |
||||
* @param dstAbsolutePath the destination path |
||||
* @param deleteSource whether to delete the source path after moving |
||||
* @param overwrite whether to overwrite the destination path if it exists |
||||
*/ |
||||
void upload(String srcLocalFileAbsolutePath, String dstAbsolutePath, boolean deleteSource, boolean overwrite); |
||||
|
||||
/** |
||||
* Download the resource from the source path to the destination path. |
||||
* |
||||
* @param srcFileAbsolutePath the source path |
||||
* @param dstAbsoluteFile the destination file |
||||
* @param overwrite whether to overwrite the destination file if it exists |
||||
*/ |
||||
void download(String srcFileAbsolutePath, String dstAbsoluteFile, boolean overwrite); |
||||
|
||||
/** |
||||
* Fetch the content of the file. |
||||
* |
||||
* @param fileAbsolutePath the file path |
||||
* @param skipLineNums the number of lines to skip |
||||
* @param limit the number of lines to read |
||||
* @return the content of the file |
||||
*/ |
||||
List<String> fetchFileContent(String fileAbsolutePath, int skipLineNums, int limit); |
||||
|
||||
/** |
||||
* Return the {@link StorageEntity} under the given path. |
||||
* <p>If the path is a file, return the file status. |
||||
* <p>If the path is a directory, return the file/directory under the directory. |
||||
* <p>If the path is not exist, will return empty. |
||||
* |
||||
* @param resourceAbsolutePath the resource absolute path, cannot be empty |
||||
*/ |
||||
List<StorageEntity> listStorageEntity(String resourceAbsolutePath); |
||||
|
||||
/** |
||||
* Return the {@link StorageEntity} which is file under the given path |
||||
* |
||||
* @param resourceAbsolutePath the resource absolute path, cannot be empty |
||||
*/ |
||||
List<StorageEntity> listFileStorageEntityRecursively(String resourceAbsolutePath); |
||||
|
||||
/** |
||||
* Return the {@link StorageEntity} under the current directory |
||||
* |
||||
* @param resourceAbsolutePath the resource absolute path, cannot be empty |
||||
*/ |
||||
StorageEntity getStorageEntity(String resourceAbsolutePath); |
||||
|
||||
} |
4
dolphinscheduler-storage-plugin/dolphinscheduler-storage-api/src/main/java/org/apache/dolphinscheduler/plugin/storage/api/StorageOperateFactory.java → dolphinscheduler-storage-plugin/dolphinscheduler-storage-api/src/main/java/org/apache/dolphinscheduler/plugin/storage/api/StorageOperatorFactory.java
4
dolphinscheduler-storage-plugin/dolphinscheduler-storage-api/src/main/java/org/apache/dolphinscheduler/plugin/storage/api/StorageOperateFactory.java → dolphinscheduler-storage-plugin/dolphinscheduler-storage-api/src/main/java/org/apache/dolphinscheduler/plugin/storage/api/StorageOperatorFactory.java
@ -0,0 +1,36 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.storage.gcs; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
@Data |
||||
@Builder |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class GcsStorageProperties { |
||||
|
||||
private String bucketName; |
||||
|
||||
private String credential; |
||||
|
||||
private String resourceUploadPath; |
||||
} |
@ -1,290 +0,0 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.apache.dolphinscheduler.plugin.storage.gcs; |
||||
|
||||
import static org.apache.dolphinscheduler.common.constants.Constants.FOLDER_SEPARATOR; |
||||
import static org.apache.dolphinscheduler.common.constants.Constants.FORMAT_S_S; |
||||
import static org.mockito.ArgumentMatchers.anyString; |
||||
import static org.mockito.Mockito.doNothing; |
||||
import static org.mockito.Mockito.doReturn; |
||||
import static org.mockito.Mockito.times; |
||||
import static org.mockito.Mockito.verify; |
||||
|
||||
import org.apache.dolphinscheduler.plugin.storage.api.StorageEntity; |
||||
import org.apache.dolphinscheduler.spi.enums.ResourceType; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
import org.junit.jupiter.api.Assertions; |
||||
import org.junit.jupiter.api.BeforeEach; |
||||
import org.junit.jupiter.api.Test; |
||||
import org.junit.jupiter.api.extension.ExtendWith; |
||||
import org.mockito.Mock; |
||||
import org.mockito.Mockito; |
||||
import org.mockito.junit.jupiter.MockitoExtension; |
||||
|
||||
import com.google.cloud.storage.BlobId; |
||||
import com.google.cloud.storage.BlobInfo; |
||||
import com.google.cloud.storage.Storage; |
||||
|
||||
@ExtendWith(MockitoExtension.class) |
||||
public class GcsStorageOperatorTest { |
||||
|
||||
private static final String CREDENTIAL_MOCK = "CREDENTIAL_MOCK"; |
||||
|
||||
private static final String BUCKET_NAME_MOCK = "BUCKET_NAME_MOCK"; |
||||
|
||||
private static final String TENANT_CODE_MOCK = "TENANT_CODE_MOCK"; |
||||
|
||||
private static final String DIR_MOCK = "DIR_MOCK"; |
||||
|
||||
private static final String FILE_NAME_MOCK = "FILE_NAME_MOCK"; |
||||
|
||||
private static final String FILE_PATH_MOCK = "FILE_PATH_MOCK"; |
||||
|
||||
private static final String FULL_NAME = "/tmp/dir1/"; |
||||
|
||||
private static final String DEFAULT_PATH = "/tmp/"; |
||||
|
||||
@Mock |
||||
private Storage gcsStorage; |
||||
|
||||
private GcsStorageOperator gcsStorageOperator; |
||||
|
||||
@BeforeEach |
||||
public void setUp() throws Exception { |
||||
gcsStorageOperator = Mockito.spy(GcsStorageOperator.class); |
||||
Mockito.doReturn(CREDENTIAL_MOCK).when(gcsStorageOperator).readCredentials(); |
||||
Mockito.doReturn(BUCKET_NAME_MOCK).when(gcsStorageOperator).readBucketName(); |
||||
Mockito.doReturn(gcsStorage).when(gcsStorageOperator).buildGcsStorage(Mockito.anyString()); |
||||
Mockito.doNothing().when(gcsStorageOperator).checkBucketNameExists(Mockito.anyString()); |
||||
|
||||
gcsStorageOperator.init(); |
||||
} |
||||
|
||||
@Test |
||||
public void testInit() throws Exception { |
||||
verify(gcsStorageOperator, times(1)).buildGcsStorage(CREDENTIAL_MOCK); |
||||
Assertions.assertEquals(CREDENTIAL_MOCK, gcsStorageOperator.getCredential()); |
||||
Assertions.assertEquals(BUCKET_NAME_MOCK, gcsStorageOperator.getBucketName()); |
||||
} |
||||
|
||||
@Test |
||||
public void testClose() throws Exception { |
||||
doNothing().when(gcsStorage).close(); |
||||
gcsStorageOperator.close(); |
||||
verify(gcsStorage, times(1)).close(); |
||||
} |
||||
|
||||
@Test |
||||
public void createTenantResAndUdfDir() throws Exception { |
||||
doReturn(DIR_MOCK).when(gcsStorageOperator).getGcsResDir(TENANT_CODE_MOCK); |
||||
doReturn(DIR_MOCK).when(gcsStorageOperator).getGcsUdfDir(TENANT_CODE_MOCK); |
||||
doReturn(true).when(gcsStorageOperator).mkdir(TENANT_CODE_MOCK, DIR_MOCK); |
||||
gcsStorageOperator.createTenantDirIfNotExists(TENANT_CODE_MOCK); |
||||
verify(gcsStorageOperator, times(2)).mkdir(TENANT_CODE_MOCK, DIR_MOCK); |
||||
} |
||||
|
||||
@Test |
||||
public void getResDir() { |
||||
final String expectedResourceDir = String.format("dolphinscheduler/%s/resources/", TENANT_CODE_MOCK); |
||||
final String dir = gcsStorageOperator.getResDir(TENANT_CODE_MOCK); |
||||
Assertions.assertEquals(expectedResourceDir, dir); |
||||
} |
||||
|
||||
@Test |
||||
public void getUdfDir() { |
||||
final String expectedUdfDir = String.format("dolphinscheduler/%s/udfs/", TENANT_CODE_MOCK); |
||||
final String dir = gcsStorageOperator.getUdfDir(TENANT_CODE_MOCK); |
||||
Assertions.assertEquals(expectedUdfDir, dir); |
||||
} |
||||
|
||||
@Test |
||||
public void mkdirWhenDirExists() { |
||||
boolean isSuccess = false; |
||||
try { |
||||
final String key = DIR_MOCK + FOLDER_SEPARATOR; |
||||
Mockito.doReturn(true).when(gcsStorageOperator).isObjectExists(key); |
||||
isSuccess = gcsStorageOperator.mkdir(TENANT_CODE_MOCK, DIR_MOCK); |
||||
|
||||
} catch (IOException e) { |
||||
Assertions.fail("test failed due to unexpected IO exception"); |
||||
} |
||||
|
||||
Assertions.assertTrue(isSuccess); |
||||
} |
||||
|
||||
@Test |
||||
public void mkdirWhenDirNotExists() { |
||||
boolean isSuccess = true; |
||||
try { |
||||
final String key = DIR_MOCK + FOLDER_SEPARATOR; |
||||
doReturn(false).when(gcsStorageOperator).isObjectExists(key); |
||||
isSuccess = gcsStorageOperator.mkdir(TENANT_CODE_MOCK, DIR_MOCK); |
||||
verify(gcsStorage, times(1)).create(Mockito.any(BlobInfo.class), Mockito.any(byte[].class)); |
||||
} catch (IOException e) { |
||||
Assertions.fail("test failed due to unexpected IO exception"); |
||||
} |
||||
|
||||
Assertions.assertTrue(isSuccess); |
||||
} |
||||
|
||||
@Test |
||||
public void getResourceFullName() { |
||||
final String expectedResourceFullName = |
||||
String.format("dolphinscheduler/%s/resources/%s", TENANT_CODE_MOCK, FILE_NAME_MOCK); |
||||
final String resourceFullName = gcsStorageOperator.getResourceFullName(TENANT_CODE_MOCK, FILE_NAME_MOCK); |
||||
Assertions.assertEquals(expectedResourceFullName, resourceFullName); |
||||
} |
||||
|
||||
@Test |
||||
public void getResourceFileName() { |
||||
final String expectedResourceFileName = FILE_NAME_MOCK; |
||||
final String resourceFullName = |
||||
String.format("dolphinscheduler/%s/resources/%s", TENANT_CODE_MOCK, FILE_NAME_MOCK); |
||||
final String resourceFileName = gcsStorageOperator.getResourceFileName(TENANT_CODE_MOCK, resourceFullName); |
||||
Assertions.assertEquals(expectedResourceFileName, resourceFileName); |
||||
} |
||||
|
||||
@Test |
||||
public void getFileName() { |
||||
final String expectedFileName = |
||||
String.format("dolphinscheduler/%s/resources/%s", TENANT_CODE_MOCK, FILE_NAME_MOCK); |
||||
final String fileName = gcsStorageOperator.getFileName(ResourceType.FILE, TENANT_CODE_MOCK, FILE_NAME_MOCK); |
||||
Assertions.assertEquals(expectedFileName, fileName); |
||||
} |
||||
|
||||
@Test |
||||
public void exists() { |
||||
boolean doesExist = false; |
||||
doReturn(true).when(gcsStorageOperator).isObjectExists(FILE_NAME_MOCK); |
||||
try { |
||||
doesExist = gcsStorageOperator.exists(FILE_NAME_MOCK); |
||||
} catch (IOException e) { |
||||
Assertions.fail("unexpected IO exception in unit test"); |
||||
} |
||||
|
||||
Assertions.assertTrue(doesExist); |
||||
} |
||||
|
||||
@Test |
||||
public void delete() { |
||||
boolean isDeleted = false; |
||||
doReturn(true).when(gcsStorage).delete(Mockito.any(BlobId.class)); |
||||
doReturn(true).when(gcsStorageOperator).isObjectExists(FILE_NAME_MOCK); |
||||
try { |
||||
isDeleted = gcsStorageOperator.delete(FILE_NAME_MOCK, true); |
||||
} catch (IOException e) { |
||||
Assertions.fail("unexpected IO exception in unit test"); |
||||
} |
||||
|
||||
Assertions.assertTrue(isDeleted); |
||||
verify(gcsStorage, times(1)).delete(Mockito.any(BlobId.class)); |
||||
} |
||||
|
||||
@Test |
||||
public void copy() { |
||||
boolean isSuccess = false; |
||||
doReturn(null).when(gcsStorage).copy(Mockito.any()); |
||||
try { |
||||
isSuccess = gcsStorageOperator.copy(FILE_PATH_MOCK, FILE_PATH_MOCK, false, false); |
||||
} catch (IOException e) { |
||||
Assertions.fail("unexpected IO exception in unit test"); |
||||
} |
||||
|
||||
Assertions.assertTrue(isSuccess); |
||||
verify(gcsStorage, times(1)).copy(Mockito.any()); |
||||
} |
||||
|
||||
@Test |
||||
public void deleteTenant() { |
||||
doNothing().when(gcsStorageOperator).deleteTenantCode(anyString()); |
||||
try { |
||||
gcsStorageOperator.deleteTenant(TENANT_CODE_MOCK); |
||||
} catch (Exception e) { |
||||
Assertions.fail("unexpected exception caught in unit test"); |
||||
} |
||||
|
||||
verify(gcsStorageOperator, times(1)).deleteTenantCode(anyString()); |
||||
} |
||||
|
||||
@Test |
||||
public void getGcsResDir() { |
||||
final String expectedGcsResDir = String.format("dolphinscheduler/%s/resources", TENANT_CODE_MOCK); |
||||
final String gcsResDir = gcsStorageOperator.getGcsResDir(TENANT_CODE_MOCK); |
||||
Assertions.assertEquals(expectedGcsResDir, gcsResDir); |
||||
} |
||||
|
||||
@Test |
||||
public void getGcsUdfDir() { |
||||
final String expectedGcsUdfDir = String.format("dolphinscheduler/%s/udfs", TENANT_CODE_MOCK); |
||||
final String gcsUdfDir = gcsStorageOperator.getGcsUdfDir(TENANT_CODE_MOCK); |
||||
Assertions.assertEquals(expectedGcsUdfDir, gcsUdfDir); |
||||
} |
||||
|
||||
@Test |
||||
public void getGcsTenantDir() { |
||||
final String expectedGcsTenantDir = String.format(FORMAT_S_S, DIR_MOCK, TENANT_CODE_MOCK); |
||||
doReturn(DIR_MOCK).when(gcsStorageOperator).getGcsDataBasePath(); |
||||
final String gcsTenantDir = gcsStorageOperator.getGcsTenantDir(TENANT_CODE_MOCK); |
||||
Assertions.assertEquals(expectedGcsTenantDir, gcsTenantDir); |
||||
} |
||||
|
||||
@Test |
||||
public void deleteDir() { |
||||
doReturn(true).when(gcsStorageOperator).isObjectExists(Mockito.any()); |
||||
gcsStorageOperator.deleteDirectory(DIR_MOCK); |
||||
verify(gcsStorage, times(1)).delete(Mockito.any(BlobId.class)); |
||||
} |
||||
|
||||
@Test |
||||
public void testGetFileStatus() throws Exception { |
||||
StorageEntity entity = |
||||
gcsStorageOperator.getFileStatus(FULL_NAME, DEFAULT_PATH, TENANT_CODE_MOCK, ResourceType.FILE); |
||||
Assertions.assertEquals(FULL_NAME, entity.getFullName()); |
||||
Assertions.assertEquals("dir1/", entity.getFileName()); |
||||
} |
||||
|
||||
@Test |
||||
public void testListFilesStatus() throws Exception { |
||||
Mockito.doReturn(null).when(gcsStorage).list(Mockito.any(), Mockito.any(Storage.BlobListOption.class), |
||||
Mockito.any(Storage.BlobListOption.class)); |
||||
List<StorageEntity> result = |
||||
gcsStorageOperator.listFilesStatus(FULL_NAME, DEFAULT_PATH, TENANT_CODE_MOCK, ResourceType.FILE); |
||||
verify(gcsStorage, times(1)).list(Mockito.any(), Mockito.any(Storage.BlobListOption.class), |
||||
Mockito.any(Storage.BlobListOption.class)); |
||||
} |
||||
|
||||
@Test |
||||
public void testListFilesStatusRecursively() throws Exception { |
||||
StorageEntity entity = new StorageEntity(); |
||||
entity.setFullName(FULL_NAME); |
||||
|
||||
doReturn(entity).when(gcsStorageOperator).getFileStatus(FULL_NAME, DEFAULT_PATH, TENANT_CODE_MOCK, |
||||
ResourceType.FILE); |
||||
doReturn(Collections.EMPTY_LIST).when(gcsStorageOperator).listFilesStatus(anyString(), anyString(), anyString(), |
||||
Mockito.any(ResourceType.class)); |
||||
|
||||
List<StorageEntity> result = |
||||
gcsStorageOperator.listFilesStatusRecursively(FULL_NAME, DEFAULT_PATH, TENANT_CODE_MOCK, |
||||
ResourceType.FILE); |
||||
Assertions.assertEquals(0, result.size()); |
||||
} |
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue